Datetime 日期和时间(当地时间而非UTC)(最大值)

Datetime 日期和时间(当地时间而非UTC)(最大值),datetime,datetime-format,maxima,Datetime,Datetime Format,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),

这些行以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));
我知道“?\*自动转换\*;”可以给出Maxima版本号,因此可能有一些未记录的方法来获取本地时间

否则,是否有任何现成的函数可以转换 UTC时间到当地时间夏令时开始/结束的给定条件
e、 g.UTC时间到英国时间(根据一年中的时间而定为GMT/BST)?

我不清楚您需要什么,但以下内容可能会有所帮助。顺便问一下,您真的需要提取部件(年、月、日等)?如果是这样,直接在Lisp中工作可能会更方便。请参阅公共Lisp Hyperspec中的DECODE-UNIVERSAL-TIME(web搜索将找到它)

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”、“美国/纽约”等,仅识别数字时区偏移量。

感谢您的帮助回复

(%i9) parse_timedate ("2016-12-19 22:01:39-08:00");
(%o9)                             3691202499
结果(第5.39.0节)(效果良好,省略参数2表示当地时间,参数2表示0表示UTC):

结果(5.30.0版)(似乎忽略参数2给出UTC+10,没有夏令时):
(如果这是真的,我必须找到另一种获取本地时间的方法,可能是通过常用的LISP命令)

(我可以看到timedate和decode universal time功能 在Maxima版本之间存在关键差异)

感谢您在网站上提及,
CLHS:在环境词典中进行分类

是否有在Maxima中工作的LISP命令列表

邮戳的主要原因是:
要为文件名(如“z title yyyymmddhhmmss.txt”)生成日期戳, 或者对于那些文件中的友好日期,例如“hh:mm dd/mm/yyyy”, 字符串操作方法是最简单的方法
我可以成功地编写代码(我不需要明确地提取单个d m y等)

以澄清问题,然后再揭示解决方案: 这些是我在MaximaV5.30中采取的步骤 要以UTC为单位以可读格式获取时间,请执行以下操作:

注:当我使用Maxima v5.30(在英国)时, 由于某些未知原因,时间总是UTC调整的 10小时,并且不针对DST进行调整

/* 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

有时我希望日期的格式为:“yyyyMMddHHmmss”。 这方面的一个功能是:

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)和DST添加小时数。 要计算某个时间是否在DST周期内,每个时区需要一个单独的函数:在英国和许多欧洲国家,一个这样的函数是:

/* 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);

DECODE-UNIVERSAL-TIME是一个Lisp函数,它不会从一个Maxima版本更改为另一个版本。但是5.30版本和5.39版本的Lisp实现可能不同。无论如何,5.30在这一点上已经很老了;不值得费心去弄清楚到底发生了什么。如果你有5.39,就用这个。关于为文件名创建时间戳,可能类似这样:
s:timedate(…);(s),
即使用字符串替换函数
ssubst
来设置
时间日期
输出。至于哪些Lisp函数在Maxima中工作,如果通过
调用,则所有Lisp函数都在Maxima中工作:Lisp(foo…
,如果通过
?foo(…)
调用,则大多数Lisp函数都在Maxima中工作,其中foo是Lisp函数<代码>??Lisp在在线参考手册中找到了一些相关信息。我发现,一种更简单的替代方法是使用
regex\u substitute
(抱歉,它没有文档记录)。示例:
regex\u subst(“\u”、“[:-]”,timedate())
产生
“2016\u12\u25\u14\u28\u31\u08\u00”
。还有其他正则表达式函数;请参见
share/stringproc/sregex.lisp
。是否可以在以“?”开头的行中使用“DECODE-UNIVERSAL-TIME”,并将项目导出到列表中。(我花了很多时间尝试和研究,但没有成功。)--更一般地说,这里有一个包含一些Maxima/LISP示例的好页面(我也查找了这些示例)此外,是否有普通用户可能感兴趣使用的LISP函数,因为我查看了CLHS列表,但没有找到很多。您可以在Maxima中将DECODE-UNIVERSAL-TIME调用为
?DECODE-UNIVERSAL-TIME()
,但它返回多个值(这是一个常见的LISP概念)马克西玛不知道该怎么处理它们。你必须用Maxima能理解的东西来包装调用,例如:
:lisp(defun$foo(time tz)(cons)(mlist)(多值列表(decode universal time tz))
,然后在Maxima中,例如
foo(0,0)
生成
[0,0,0,1,1900,0,false,0]
。对于Maxima/Lisp示例,我没有很好的参考;如果您有特定的问题,maxima讨论邮件列表是一个很好的提问场所。
/* 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);
load("C:\\MyFolder\\MyFile.mac");
SecUTCIsDSTUK(absolute_real_time());
SecUTCIsDSTUK(absolute_real_time()+86400*180);