В БД хранится дата в колонке типа datetime в некотором непонятном формате, и к ней — поправка под названием TimeZone в виде числа.
Опытным путем установлено, что:
1. При выборе в UI часового пояса "GMT (Casablanka, Monrovia, Reykjavik)" (типа, GMT+0, надо полагать), время выводится на форму так, как оно хранится в базе (по крайней мере, отображается SQL SMS), при этом в БД записывается TimeZone == 31.
2. При выборе в UI часового пояса "GMT (Greenwich Mean Time: Dublin, Edinburgh)" (тоже GMT+0???), время выводится на форму со смещением на час вперед, по сравнению с тем, как оно хранится в базе, при этом в БД записывается TimeZone == 2.
3. При выборе в UI часового пояса "GMT +3 (Moscow)", время выводится на форму со смещением на 4 часа вперед, по сравнению с тем, как оно хранится в базе, при этом в БД записывается TimeZone == 51.
Вопросы:
1. Почему два GMT+0, один из которых на самом деле +1? Почему GMT +3 (Moscow) на деле +4? Иными словами, что это за формат хранения даты?
2. Как кодируется в этой системе TimeZone? 2, 31, 51 — никакого намека на +n.
Что интересует в конечном итоге, это как имея инстансы DateTime dt и int timeZone получить строку (например, с помощью .ToString("d")). Но с этим я и сам справлюсь, если будут ответы на вопросы 1 и 2.
Здравствуйте, Аноним, Вы писали:
А>1. Почему два GMT+0, один из которых на самом деле +1? Почему GMT +3 (Moscow) на деле +4? Иными словами, что это за формат хранения даты?
Вы учли переход на летнее/зимнее время? Вообще тупость хранить в базе время в локальном формате, так делают только уроды. В базе должно быть время по гринвичу и точка.
летнее и зимнее время — это одна зона времени, но с разным временем. Если у вас Windows система, посмотрите в реестре как зоны времени пишутся, например зону Moscow
А вот цифры — это какое-то доморощеное произведение искусства, ищите, где у вас в программе или может в базе лежит табличка с переводом.
Я сомневаюсь, что может быть где-то стандартный список с цифирьками, зоны времени же еще и меняются. Вот придумал Медведев, что у нас их многовато — и Microsoft вынужден обновление к Windows выпускать с новым списком...
В общем случае, для зон времени хранятся названия и сдвиг от GMT, еще в какой-нибудь форме записывается, по каким правилам осуществляется переход на зимнее/летнее время, плюс иногда хранятся исторические зоны времени, если что-то законодательно менялось. Поэтому, если у вас не дай бог в базе есть Парагвай, то все совсем плохо, потому что там каждый год переход по-разному происходит.
А уж каждая программа в силу своей испорченности пытается имеющуюся информацию трактовать. Вот, например, почитайте: http://blogs.msdn.com/b/bclteam/archive/2007/06/07/exploring-windows-time-zones-with-system-timezoneinfo-josh-free.aspx
И это не только в Windows так, iCal спецификация на этот счет примерно так же мутно выглядит.
Здравствуйте, Аноним, Вы писали:
А>В БД хранится дата в колонке типа datetime в некотором непонятном формате, и к ней — поправка под названием TimeZone в виде числа.
А>Опытным путем установлено, что:
А>1. При выборе в UI часового пояса "GMT (Casablanka, Monrovia, Reykjavik)" (типа, GMT+0, надо полагать)
Точнее, GMT+0 без перехода на летнее время А>, время выводится на форму так, как оно хранится в базе (по крайней мере, отображается SQL SMS), при этом в БД записывается TimeZone == 31. А>2. При выборе в UI часового пояса "GMT (Greenwich Mean Time: Dublin, Edinburgh)" (тоже GMT+0???)
Точнее, GMT+0 с переходом на летнее время А>, время выводится на форму со смещением на час вперед, по сравнению с тем, как оно хранится в базе, при этом в БД записывается TimeZone == 2. А>3. При выборе в UI часового пояса "GMT +3 (Moscow)", время выводится на форму со смещением на 4 часа вперед, по сравнению с тем, как оно хранится в базе, при этом в БД записывается TimeZone == 51.
Опять же, учтён переход на летнее время, как уже указал 0K
А>Вопросы:
А>1. Почему два GMT+0, один из которых на самом деле +1?
Это разные таймзоны. Время в них совпадет только без учёта летнего время А> Почему GMT +3 (Moscow) на деле +4? Иными словами, что это за формат хранения даты?
Летнее время
А>2. Как кодируется в этой системе TimeZone? 2, 31, 51 — никакого намека на +n.
Это просто коды таймзон, к смещениям отношения не имеют. Очень похожи на коды CDO:
Здравствуйте, notacat, Вы писали:
N>действительно похоже. Только с летним временем как-то все мутно, оно же тут вообще не фигурирует.
Ничего не мутно. Сейчас лето — вот оно и прибавляется.
В идентификаторе таймзоны оно не фигурирует, так как с летним временем или без — это одна и та же таймзона.
Просто для разного времени года смещение разное.
N>>действительно похоже. Только с летним временем как-то все мутно, оно же тут вообще не фигурирует. V>Ничего не мутно. Сейчас лето — вот оно и прибавляется.
Это не прибавляет ясности в вопросе, как из DateTime и номера зоны времени получить правильную строку для любой зоны времени, а не для локальной. Это локально у нас летнее время, а где-то может вообще перехода нет, или DateTime из базы представляет собой не сегодняшний день, а что-нибудь типа 1 января.
Здравствуйте, notacat, Вы писали:
N>>>действительно похоже. Только с летним временем как-то все мутно, оно же тут вообще не фигурирует. V>>Ничего не мутно. Сейчас лето — вот оно и прибавляется. N>Это не прибавляет ясности в вопросе, как из DateTime и номера зоны времени получить правильную строку для любой зоны времени, а не для локальной.
Смотря что понимать под "правильной строкой". Строкой чего?
N> Это локально у нас летнее время, а где-то может вообще перехода нет,
Тогда это другая таймзона
N> DateTime из базы представляет собой не сегодняшний день, а что-нибудь типа 1 января.
Тогда для него будет зимнее смещение
В общем, единственное, что нужно сделать, это как-то связать идентификаторы таймзон с инстансом класса TimeZoneInfo, а дальше уже делать с ним всё, что нужно. Простого способа связать я сходу не знаю, но набить 50 соответствий в принципе можно и руками.
Re[6]: Timezone?
От:
Аноним
Дата:
29.09.10 12:32
Оценка:
Здравствуйте, vmpire, Вы писали:
V>В общем, единственное, что нужно сделать, это как-то связать идентификаторы таймзон с инстансом класса TimeZoneInfo, а дальше уже делать с ним всё, что нужно. Простого способа связать я сходу не знаю, но набить 50 соответствий в принципе можно и руками.
Соответствий между числами и строковым id, используемым в TimeZoneInfo.FindSystemTimeZoneById()?
Здравствуйте, 0K, Вы писали:
0K>Вы учли переход на летнее/зимнее время? Вообще тупость хранить в базе время в локальном формате, так делают только уроды. В базе должно быть время по гринвичу и точка.
Вообще тупость отсчитывать время в GMT, так делают только уроды. В базе должно быть время UTC и точка.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, vmpire, Вы писали:
V>>В общем, единственное, что нужно сделать, это как-то связать идентификаторы таймзон с инстансом класса TimeZoneInfo, а дальше уже делать с ним всё, что нужно. Простого способа связать я сходу не знаю, но набить 50 соответствий в принципе можно и руками.
А>Соответствий между числами и строковым id, используемым в TimeZoneInfo.FindSystemTimeZoneById()?
Например так.
Хотя, с них станется быть локализованными, что усложняет задачу.
Если это так, то можно использовать их индекс (который DWORD в Registry) в качестве идентификатора
Здравствуйте, SE, Вы писали:
0K>>Вы учли переход на летнее/зимнее время? Вообще тупость хранить в базе время в локальном формате, так делают только уроды. В базе должно быть время по гринвичу и точка.
SE>Вообще тупость отсчитывать время в GMT, так делают только уроды. В базе должно быть время UTC и точка.
Вообще тупость хранить время. Время нужно тратить и точка!
V>Если это так, то можно использовать их индекс (который DWORD в Registry) в качестве идентификатора
у меня в реестре у зон времени вообще нет DWORD параметров (Виста)
V>>Если это так, то можно использовать их индекс (который DWORD в Registry) в качестве идентификатора N>у меня в реестре у зон времени вообще нет DWORD параметров (Виста)
и кстати, в моем реестре 97 разных зон времени, не 50
Здравствуйте, notacat, Вы писали:
V>>>Если это так, то можно использовать их индекс (который DWORD в Registry) в качестве идентификатора N>>у меня в реестре у зон времени вообще нет DWORD параметров (Виста) N>и кстати, в моем реестре 97 разных зон времени, не 50
Ну, значит часть в енуме не используется
Здравствуйте, notacat, Вы писали:
V>>Если это так, то можно использовать их индекс (который DWORD в Registry) в качестве идентификатора N>у меня в реестре у зон времени вообще нет DWORD параметров (Виста)
Тогда не знаю. Возможно, Id всё-таки не локализуемое.
Re[2]: Timezone?
От:
Аноним
Дата:
29.09.10 23:05
Оценка:
Вот придумал Медведев, что у нас их многовато — и Microsoft вынужден обновление к Windows выпускать с новым списком...
Вам вааще с Медведевым повезло — вот было бы у вас типа дерьмократическое чмо типа Юща или Явлинского или еще кого бы то нибыло, пиндосы бы васм время переводили — у вас бы его уже не было )))))
Здравствуйте, vmpire, Вы писали:
V>>>В общем, единственное, что нужно сделать, это как-то связать идентификаторы таймзон с инстансом класса TimeZoneInfo, а дальше уже делать с ним всё, что нужно. Простого способа связать я сходу не знаю, но набить 50 соответствий в принципе можно и руками. А>>Соответствий между числами и строковым id, используемым в TimeZoneInfo.FindSystemTimeZoneById()? V>Например так. V>Хотя, с них станется быть локализованными, что усложняет задачу. V>Если это так, то можно использовать их индекс (который DWORD в Registry) в качестве идентификатора
MSDN явно оговаривает, что StandardName — локализованы, а про Id такого нет. Да и было бы глупо, если бы так было.
Проблема в другом. Результат такого кода:
var zones = TimeZoneInfo.GetSystemTimeZones();
Console.WriteLine("The local system has the following {0} time zones", zones.Count);
foreach (TimeZoneInfo zone in zones)
{
Console.WriteLine(zone.Id);
}
Советы, как сопоставить малой кровью, с благодарностью принимаются.
UTC (UTC) Universal Coordinated Time cdoUTC 0
GMT Standard Time (GMT) Casablanca, Monrovia cdoMonrovia 31
Greenwich Standard Time (GMT) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London cdoLisbon 2
W. Europe Standard Time (GMT) Greenwich Mean Time; Dublin, Edinburgh, London cdoGMT 1
Central Europe Standard Time (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna cdoBerlin 4
Romance Standard Time (GMT+01:00) Belgrade, Pozsony, Budapest, Ljubljana, Prague cdoPrague 6
Central European Standard Time (GMT+01:00) Brussels, Copenhagen, Madrid, Paris cdoParis 3
W. Central Africa Standard Time (GMT+01:00) Paris, Madrid, Brussels, Copenhagen cdoParis 3
Jordan Standard Time (GMT+01:00) Prague, Central Europe cdoPrague 6
GTB Standard Time (GMT+01:00) Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb cdoSarajevo 2
Middle East Standard Time (GMT+01:00) West Central Africa cdoWestCentralAfrica 69
Egypt Standard Time (GMT+02:00) Athens, Istanbul, Minsk cdoAthens 7
Syria Standard Time (GMT+02:00) Bucharest cdoEasternEurope 5
South Africa Standard Time (GMT+02:00) Cairo cdoCairo 49
FLE Standard Time (GMT+02:00) Harare, Pretoria cdoHarare 50
Israel Standard Time (GMT+02:00) Helsinki, Riga, Tallinn cdoHelsinki 59
E. Europe Standard Time (GMT+02:00) Israel, Jerusalem Standard Time cdoIsrael 27
Namibia Standard Time (GMT+03:00) Baghdad cdoBaghdad 26
Arabic Standard Time (GMT+03:00) Arab, Kuwait, Riyadh cdoArab 74
Arab Standard Time (GMT+03:00) Moscow, St. Petersburg, Volgograd cdoMoscow 51
Russian Standard Time (GMT+03:00) East Africa, Nairobi cdoEastAfrica 56
E. Africa Standard Time (GMT+03:30) Tehran cdoTehran 25
Iran Standard Time (GMT+04:00) Abu Dhabi, Muscat cdoAbuDhabi 24
Arabian Standard Time (GMT+04:00) Baku, Tbilisi, Yerevan cdoCaucasus 54
Azerbaijan Standard Time (GMT+04:30) Kabul cdoKabul 48
Mauritius Standard Time (GMT+05:00) Ekaterinburg cdoEkaterinburg 58
Georgian Standard Time (GMT+05:00) Islamabad, Karachi, Tashkent cdoIslamabad 47
Caucasus Standard Time (GMT+05:30) Kolkata, Chennai, Mumbai, New Delhi, India Standard Time cdoBombay 23
Afghanistan Standard Time (GMT+05:45) Kathmandu, Nepal cdoNepal 62
Ekaterinburg Standard Time (GMT+06:00) Almaty, Novosibirsk, North Central Asia cdoAlmaty 46
Pakistan Standard Time (GMT+06:00) Astana, Dhaka cdoDhaka 71
West Asia Standard Time (GMT+06:00) Sri Jayawardenepura, Sri Lanka cdoSriLanka 66
India Standard Time (GMT+06:30) Rangoon cdoRangoon 61
Sri Lanka Standard Time (GMT+07:00) Bangkok, Hanoi, Jakarta cdoBangkok 22
Nepal Standard Time (GMT+07:00) Krasnoyarsk cdoKrasnoyarsk 64
Central Asia Standard Time (GMT+08:00) Beijing, Chongqing, Hong Kong SAR, Urumqi cdoBeijing 45
Bangladesh Standard Time (GMT+08:00) Irkutsk, Ulaan Bataar cdoIrkutsk 63
N. Central Asia Standard Time (GMT+08:00) Kuala Lumpur, Singapore cdoSingapore 21
Myanmar Standard Time (GMT+08:00) Perth, Western Australia cdoPerth 73
SE Asia Standard Time (GMT+08:00) Taipei cdoTaipei 75
North Asia Standard Time (GMT+09:00) Osaka, Sapporo, Tokyo cdoTokyo 20
China Standard Time (GMT+09:00) Seoul, Korea Standard time cdoSeoul 72)
North Asia East Standard Time (GMT+09:00) Yakutsk cdoYakutsk 70
Singapore Standard Time (GMT+09:30) Adelaide, Central Australia cdoAdelaide 19
W. Australia Standard Time (GMT+09:30) Darwin cdoDarwin 44
Taipei Standard Time (GMT+10:00) Brisbane, East Australia cdoBrisbane 18
Ulaanbaatar Standard Time (GMT+10:00) Canberra, Melbourne, Sydney, Hobart (year 2000 only) cdoSydney 76
Tokyo Standard Time (GMT+10:00) Guam, Port Moresby cdoGuam 43
Korea Standard Time (GMT+10:00) Hobart, Tasmania cdoHobart 42
Yakutsk Standard Time (GMT+10:00) Vladivostok cdoVladivostock 68
Cen. Australia Standard Time (GMT+11:00) Magadan, Solomon Is., New Caledonia cdoMagadan 41
AUS Central Standard Time (GMT+12:00) Auckland, Wellington cdoWellington 17
E. Australia Standard Time (GMT+12:00) Fiji Islands, Kamchatka, Marshall Is. cdoFiji 40
AUS Eastern Standard Time (GMT+13:00) Nuku'alofa, Tonga cdoTonga 67
West Pacific Standard Time (GMT-01:00) Azores cdoAzores 29
Tasmania Standard Time (GMT-01:00) Cape Verde Is. cdoCapeVerde 53
Vladivostok Standard Time (GMT-02:00) Mid-Atlantic cdoMidAtlantic 30
Central Pacific Standard Time (GMT-03:00) Brasilia cdoBrasilia 8
New Zealand Standard Time (GMT-03:00) Buenos Aires, Georgetown cdoBuenosAires 32
UTC+12 (GMT-03:00) Greenland cdoGreenland 60
Fiji Standard Time (GMT-03:30) Newfoundland cdoNewfoundland 28
Kamchatka Standard Time (GMT-04:00) Atlantic Time (Canada) cdoAtlanticCanada 9
Tonga Standard Time (GMT-04:00) Caracas, La Paz cdoCaracas 33
Azores Standard Time (GMT-04:00) Santiago cdoSantiago 65
Cape Verde Standard Time (GMT-05:00) Bogota, Lima, Quito cdoBogota 35
UTC-02 (GMT-05:00) Eastern Time (US & Canada) cdoEastern 10
Mid-Atlantic Standard Time (GMT-05:00) Indiana (East) cdoIndiana 34
E. South America Standard Time (GMT-06:00) Central America cdoCentralAmerica 55
Argentina Standard Time (GMT-06:00) Central Time (US & Canada) cdoCentral 11
SA Eastern Standard Time (GMT-06:00) Mexico City, Tegucigalpa cdoMexicoCity 37
Greenland Standard Time (GMT-06:00) Saskatchewan cdoSaskatchewan 36
Montevideo Standard Time (GMT-07:00) Arizona cdoArizona 38
Newfoundland Standard Time (GMT-07:00) Mountain Time (US & Canada) cdoMountain 12
Paraguay Standard Time (GMT-08:00) Pacific Time (US & Canada); Tijuana cdoPacific 13
Atlantic Standard Time (GMT-09:00) Alaska cdoAlaska 14
Central Brazilian Standard Time (GMT-10:00) Hawaii cdoHawaii 15
SA Western Standard Time (GMT-11:00) Midway Island, Samoa cdoMidwayIsland 16
Pacific SA Standard Time (GMT-12:00) Eniwetok, Kwajalein, Dateline Time
Venezuela Standard Time
SA Pacific Standard Time
Eastern Standard Time
US Eastern Standard Time
Central America Standard Time
Central Standard Time
Central Standard Time (Mexico)
Canada Central Standard Time
US Mountain Standard Time
Mountain Standard Time (Mexico)
Mountain Standard Time
Pacific Standard Time (Mexico)
Pacific Standard Time
Alaskan Standard Time
Hawaiian Standard Time
UTC-11
Samoa Standard Time
Dateline Standard Time