Летнее время "ошибка" - PullRequest
       0

Летнее время "ошибка"

9 голосов
/ 26 апреля 2011

Вот подсчет количества часов между двумя последовательными днями:

(AbsoluteTime[{2011, 3, 14}] - AbsoluteTime[{2011, 3, 13}]) / 3600

Так что вы можете не удивиться, что Mathematica вернет 24. Но это удивительно. На любом другом языке программирования будет 23, потому что 13 марта стало началом летнего времени. Мне нужно, чтобы моя программа Mathematica соответствовала другим языкам в этом отношении. Что бы вы порекомендовали?

Для ясности по поводу проблемы: AbsoluteTime[{2011,3,13}] дает 3508963200. Вычтите эпоху Unix, и это время Unix 1299988800. Но дайте это unixtime любому другому языку программирования и спросите его, какой дате он соответствует, и он скажет 12 марта вместо 13 марта. (То же самое будет хорошо для 14 марта.)

(Хорошо, я знаю, что вам не терпится узнать, почему я хотел бы соответствовать всем этим явно нарушенным языкам. Ну, во-первых, у других языков есть смысл: благодаря «прыгучести» полночь 14 марта была в 23 часа после полуночи 13 марта. Почему меня это волнует: мы используем unixtime в качестве канонического представления дат. Поэтому, когда я хочу передать «2011-03-13 00:00 EST» другой программе, я отправляю AbsoluteTime минус эпоху Unix. Это прекрасно работает в Mathematica. Когда я конвертирую это unixtime обратно, я снова получаю «2011-03-13 00:00 EST». Но если я отправляю это unixtime в другую программу, он интерпретирует его как «2011-03-12 23:00 EST», что оказывается проблемой, поскольку это был предыдущий день.)

Ответы [ 3 ]

4 голосов
/ 26 апреля 2011

Вы можете использовать Java для преобразования туда и обратно из времени Unix:

Needs["JLink`"]
LoadJavaClass["java.util.Calendar"]

ToUnixTime[year_, month_, day_, hour_:0, minute_:0, second_:0] :=
  JavaBlock[
    Module[{calendar}
    , calendar = java`util`Calendar`getInstance[]
    ; calendar@set[year, month - 1, day, hour, minute, second]
    ; Floor[calendar@getTimeInMillis[] / 1000]
    ]
  ]

FromUnixTime[time_Integer] :=
  JavaBlock[
    Module[{calendar}
    , calendar = java`util`Calendar`getInstance[]
    ; calendar@setTimeInMillis[time * 1000]
    ; calendar@getTime[]@toString[]
    ]
  ]

Пример использования:

In[19]:= ToUnixTime[2011, 4, 26, 1, 2, 3]
Out[19]= 1303801323

In[20]:= FromUnixTime[1303801323]
Out[20]= "Tue Apr 26 01:02:03 MDT 2011"

Как написано, предыдущие определения будут использовать ваш местный часовой пояс иНастройки локали в конверсиях.

3 голосов
/ 27 апреля 2011

Я опубликовал соответствующий вопрос в comp.soft-sys.math.mathematica 8/4/10:

http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/6f50f6930f1ac325/

Оказывается, что есть (была?) Ошибка в версии M7 для Mac, которая по существу игнорировала спецификацию Timezone при вызовах AbsoluteTime. Я думаю, что проблема была исправлена ​​в M8, но я не уверен.

3 голосов
/ 27 апреля 2011

Вы можете попробовать что-то вроде этого:

tzDreeves = {"Buenos Aires", "13 March", "13 September", 3, 4};

tZone[date_, tz_] := 
 Piecewise[{{tz[[4]],
   First@
    DateDifference[tz[[2]]<>" "<>DateString[date,"Year"], date, "Second"] > 0 &&
   First@
    DateDifference[tz[[3]]<>" "<>DateString[date,"Year"], date, "Second"] < 0}},
 tz[[5]]];

myTimeDif[d1_, d2_, tz_] := 
 DateDifference[DateList@AbsoluteTime[d1, TimeZone -> tZone[d1, tz]], 
                DateList@AbsoluteTime[d2, TimeZone -> tZone[d2, tz]], "Second"]


myTimeDif["March 13, 2011", "March 14, 2011", tzDreeves]
myTimeDif["March 12, 2011", "March 13, 2011", tzDreeves]  

->

{82800,Second}  -> 23 hours
{86400,Second}  -> 24 hours   

В следующем примере вы можете увидеть эффект от DS.Мы наносим разницу во времени на фиксированную дату через границу летнего времени:

data = Table[{
         DateList@DatePlus["March 12, 2011, 11PM", {i 10, "Minute"}], 
         First@myTimeDif[DatePlus["March 12, 2011, 11PM", {i 10, "Minute"}], 
                         "March 14, 2011, 2 AM", tzDreeves]},
       {i, 1, 13}];

DateListPlot[data, 
 DateTicksFormat -> {"MonthNameShort", " ", "Day", "\n ", "Time"}, 
 GridLines -> {{{{2011, 3, 13}, Red}}, None}, 
 PlotStyle -> PointSize[Large]]

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...