дата и время (местное время вместо UTC) (Maxima)

Эти строки дают дату и время в формате UTC:

t:timedate(absolute_real_time() - (10*3600));
t0:substring(t,1,20);
t1:concat(substring(t,12,17), " ", substring(t,9,11), "/", substring(t,6,8), "/", substring(t,1,5));
t2:concat(substring(t,1,5), substring(t,6,8), substring(t,9,11), substring(t,12,14), substring(t,15,17), substring(t,18,20));

Я знаю, что '?\*autoconf\-версия\*;' может дать номер версии Maxima, так что, возможно, есть какой-то недокументированный способ получить местное время.

В противном случае существуют какие-либо готовые функции, которые могут преобразовывать время UTC в местное время с учетом условий начала/окончания летнего времени, например. Время UTC по времени Великобритании (которое является GMT/BST в зависимости от времени года)?


person vafylec    schedule 19.12.2016    source источник


Ответы (3)


Мне не ясно, что именно вам нужно, но, возможно, поможет следующее. Кстати, вам действительно нужно извлекать части (год, месяц, день и т. д.)? Если это так, возможно, было бы удобнее работать непосредственно в Лиспе. См. DECODE-UNIVERSAL-TIME в Common Lisp Hyperspec (поиск в Интернете найдет его).

timedate now (в только что выпущенной версии Maxima 5.39) принимает необязательный аргумент, представляющий собой смещение часового пояса в часах (плюс или минус). Смещение часового пояса может быть нецелым (например, 2,5). Смещение 0 указывает на UTC. Если смещение опущено, время форматируется в местном часовом поясе.

(%i5) t:absolute_real_time();
(%o5)                             3691202499
(%i6) timedate (t, 0);
(%o6)                      2016-12-20 06:01:39+00:00
(%i7) timedate (t);
(%o7)                      2016-12-19 22:01:39-08:00

Обратите внимание, что флаг перехода на летнее время применяется в «время времени». Вот время следующего лета, когда действует летнее время.

(%i8) timedate (t + 6*30.25*24*3600);
(%o8)                      2017-06-19 11:01:39-07:00

Функция parse_timedate также была (в Maxima 5.39) обновлена ​​для распознавания смещения часовых поясов.

(%i9) parse_timedate ("2016-12-19 22:01:39-08:00");
(%o9)                             3691202499

Как и в случае с timedate, если смещение опущено, предполагается, что оно находится в местном часовом поясе.

(%i10) parse_timedate ("2016-12-19 22:01:39");
(%o10)                            3691202499

Также обратите внимание, что Maxima не распознает никаких символических индикаторов часовых поясов, таких как «UTC», «GMT», «EDT», «America/New_York» и т. д., только числовые смещения часовых поясов.

person Robert Dodier    schedule 20.12.2016

Чтобы прояснить проблему, прежде чем раскрыть решение: вот шаги, которые я предпринимаю в Maxima v5.30, чтобы получить время в формате UTC в удобочитаемом формате:

Примечание. Когда я использую Maxima v5.30 (в Великобритании), по какой-то неизвестной причине время всегда корректируется по Гринвичу на 10 часов и не корректируется по летнему времени.

/* 1st Jan 2017 12 noon: */
timedate(3692260800); /* "2017-01-01 22:00:00+10:00" */
timedate(3692260800-10*3600); /* "2017-01-01 12:00:00+10:00" */
substring(timedate(3692260800-10*3600),1,20); /* "2017-01-01 12:00:00" */

Примечание: timedate работает лучше/по-другому в более поздних версиях Maxima, но некоторые учреждения рекомендуют устанавливать определенную версию Maxima.

Иногда мне нужна дата в форме: «ггггММддЧЧммсс». Функция для этого:

SecUTCToDate(vSec,vHour):=
block([d1,d2],
d1:timedate(vSec+vHour*3600),
d2:concat(substring(d1,1,5), substring(d1,6,8), substring(d1,9,11), substring(d1,12,14), substring(d1,15,17), substring(d1,18,20)),
parse_string(d2)
);

Примечание: [d1,d2] сохраняет эти переменные локальными внутри блока, а не глобальными.

Чтобы получить местное время, мне нужно добавить часы в зависимости от моего часового пояса (0 в Великобритании) и летнего времени. Чтобы вычислить, находится ли время в периоде летнего времени, требуется отдельная функция для каждого часового пояса: в Великобритании и многих европейских странах одна из таких функций:

/* correct for the years 1900-2200 inclusive */
SecUTCIsDSTUK(vSec):=
block([vLeap,vDaysMar25,vDaysOct25,vWDayMar25,vWDayOct25,vRange1,vRange2],
vYear : parse_string(substring(timedate(vSec),1,5)),
vLeap : floor((vYear-1900)/4), if (vYear>=2100) then vLeap : vLeap-1,
vDaysMar25 : (vYear-1900)*365 + vLeap + 83,
vDaysOct25 : vDaysMar25 + 214,
vWDayMar25 : mod(vDaysMar25+1,7),
vWDayOct25 : mod(vDaysOct25+1,7),
vRange1 : (vDaysMar25+mod(-vWDayMar25,7))*86400 + 3600,
vRange2 : (vDaysOct25+mod(-vWDayOct25,7))*86400 + 3600,
if ((vSec >= vRange1) and (vSec < vRange2)) then 1 else 0);

Вы можете создать файл Mac с такой функцией и вызывать функцию при необходимости, например:

load("C:\\MyFolder\\MyFile.mac");
SecUTCIsDSTUK(absolute_real_time());
SecUTCIsDSTUK(absolute_real_time()+86400*180);
person vafylec    schedule 01.03.2017

спасибо за ваш полезный ответ,

результаты (v. 5.39.0) (работает нормально, параметр 2 опущен, дает местное время, параметр 2 как 0 дает UTC):

t:3691202499;
timedate (t);
timedate (t + 6*30.25*24*3600);
timedate (t + 6*30*24*3600);
timedate (t, 0);
timedate (t + 6*30.25*24*3600, 0);
timedate (t + 6*30*24*3600, 0);
:lisp (decode-universal-time 3691202499)
:lisp (decode-universal-time 3691202499 0)
:lisp (decode-universal-time 3706754499)
:lisp (decode-universal-time 3706754499 0)

3691202499
"2016-12-20 06:01:39+00:00"
"2017-06-19 19:01:39+01:00"
"2017-06-18 07:01:39+01:00"
"2016-12-20 06:01:39+00:00"
"2017-06-19 18:01:39+00:00"
"2017-06-18 06:01:39+00:00"
39 1 6 20 12 2016 1 NIL 0
39 1 6 20 12 2016 1 NIL 0
39 1 7 18 6 2017 6 T 0
39 1 6 18 6 2017 6 NIL 0

результаты (v. 5.30.0) (кажется, что параметр 2 опущен, дает UTC+10 без перехода на летнее время):
(если это правда, мне придется найти другой способ получить местное время, возможно, с помощью Common ЛИСП-команды)

t:3691202499;
timedate (t);
timedate (t + 6*30.25*24*3600);
timedate (t + 6*30*24*3600);
:lisp (decode-universal-time 3691202499)
:lisp (decode-universal-time 3691202499 0)
:lisp (decode-universal-time 3706754499)
:lisp (decode-universal-time 3706754499 0)

3691202499
"2016-12-20 16:01:39+10:00"
"2017-06-20 04:01:39.0+10:00"
"2017-06-18 16:01:39+10:00"
39 1 16 20 12 2016 1 NIL -10
39 1 6 20 12 2016 1 NIL 0
39 1 16 18 6 2017 6 NIL -10
39 1 6 18 6 2017 6 NIL 0

(Я вижу, что функции timedate и decode-universal-time имеют ключевые отличия между версиями Maxima)

спасибо за упоминание веб-сайта,
CLHS: Section The Environment Dictionary
http://clhs.lisp.se/Body/c_enviro.htm

есть ли список команд LISP, которые работают в Maxima?

основная причина использования метки даты заключается в следующем:
создавать метки даты для имен файлов, таких как 'z title yyyymmddhhmmss.txt', или для понятных дат внутри этих файлов, таких как 'hh:mm dd/mm/yyyy', метод манипуляции со строками был самым простым методом, который я мог успешно закодировать (мне явно не нужно извлекать отдельные d m y и т. д.)

person vafylec    schedule 20.12.2016
comment
Что ж, DECODE-UNIVERSAL-TIME — это функция Лиспа, и она не меняется от одной версии Maxima к другой. Но возможно, что реализации Lisp вашей версии 5.30 и версии 5.39 отличаются. В любом случае, версия 5.30 уже устарела; не стоит пытаться понять, что происходит. Если у вас 5.39, просто используйте его. О создании временных меток для имен файлов, может быть что-то вроде этого: s:timedate(...); ssubst("_", " ", (ssubst ("_", ":", s))); т.е. используйте функцию подстановки строк ssubst, чтобы исправить вывод timedate. - person Robert Dodier; 21.12.2016
comment
Что касается того, какие функции Лиспа работают в Maxima, то все функции Лиспа работают в Максиме, если они вызываются через :lisp (foo ...), и большинство из них работают, если вызываются через ?foo(...), где FOO — это функция Лиспа. ?? Lisp находит нужную информацию в интерактивном справочном руководстве. - person Robert Dodier; 21.12.2016
comment
Я обнаружил, что более простой способ выполнить замену - использовать regex_substitute (извините, это недокументировано). Пример: regex_subst("_", "[ :-]", timedate()) дает "2016_12_25_14_28_31_08_00". Существуют и другие функции регулярных выражений; см. share/stringproc/sregex.lisp. - person Robert Dodier; 26.12.2016
comment
Можно ли использовать «DECODE-UNIVERSAL-TIME» в строке, которая начинается с «?», и экспортировать элементы в список. (Я потратил много времени на попытки и исследования, но не смог этого сделать.) -- В общем, есть хорошая страница с некоторыми примерами Maxima/LISP (я тоже искал их). -- Кроме того, есть ли какие-либо функции LISP, которые могли бы заинтересовать обычного пользователя, потому что я просмотрел список CLHS и не нашел многих. - person vafylec; 26.12.2016
comment
Ну, вы можете вызвать DECODE-UNIVERSAL-TIME как ?decode\-universal\-time() в Maxima, но он возвращает несколько значений (это концепция Common Lisp), и Maxima не знает, что с ними делать. Вам нужно будет обернуть вызов чем-то, что понимает Maxima, например: :lisp (defun $foo (time tz) (cons '(mlist) (multiple-value-list (decode-universal-time time tz)))), а затем, например. foo(0, 0) дает [0, 0, 0, 1, 1, 1900, 0, false, 0] в Максиме. У меня нет хорошего справочника по примерам Maxima/Lisp; если у вас есть конкретные вопросы, список рассылки maxima-discuss — хорошее место, чтобы задать их. - person Robert Dodier; 26.12.2016
comment
О полезных функциях Лиспа вы можете прочитать в учебных пособиях, таких как The Common Lisp Cookbook или Практический Common Lisp. Common Lisp — интересный и полезный язык, который стоит изучать сам по себе. - person Robert Dodier; 26.12.2016
comment
Ну, я не люблю слишком быстро сдаваться, я надеялся сделать 2 функции GMT/BST от/до даты, совместимые с 5.30 и 5.39, частично для проверки моих навыков Maxima/LISP. -- Им нужно будет получить индекс дня недели и преобразовать YMDHMS в S, однако, если 'block (?sleep(1));' работает, но 'block (:lisp (sleep 1));' нет, т.е. если вы не можете использовать ':lisp' в функции или блоке, я не уверен, что смогу продолжить. - person vafylec; 26.12.2016
comment
Большое спасибо за помощь, пишу гайд по Максиме, ссылка появится на странице моего профиля в ближайшие несколько месяцев. -- Мои запросы выполнены на среднесрочную перспективу, хотя я могу предвидеть некоторые возможные проблемы с добавлением в txt в будущем. -- В настоящее время решение проблем с Maxima обычно занимает в 2-3 раза больше времени поиска, чем другие запросы. Потребуется всего несколько хороших онлайн-руководств, чтобы популярность Maxima взлетела до небес. Эта серия видео оказалась для меня бесценной. Учебные пособия по Maxima CAS — YouTube youtube.com/playlist?list=PLEDEE2F7C6750729F - person vafylec; 26.12.2016
comment
Если у вас есть дополнительные вопросы, я советую задать их в списке рассылки Maxima. См.: maxima.sourceforge.net/maximalist.html - person Robert Dodier; 27.12.2016
comment
Это правда, что вы не можете поместить :lisp внутрь block, но смысл определения такой функции, как :lisp (defun $foo ...), как я показывал ранее, заключается в том, что foo является функцией, которую вы можете вызывать из Maxima, и она возвращает результат, понятный Maxima. - person Robert Dodier; 27.12.2016