我希望找到使用Lua的时区偏移量,但是我面临着看起来很奇怪的行为,所以我必须遗漏一些东西。
我正在使用代码:
local t1 = os.time();
local t2 = os.time( os.date( "!*t" ) );
print( t1, t2, t1 - t2 );
local t1 = os.time( os.date( "*t" ) );
local t2 = os.time( os.date( "!*t" ) );
print( t1, t2, t1 - t2 );
local t1 = os.date( "%c" );
local t2 = os.date( "!%c" );
print( t1, t2 );
local t1 = os.time( os.date( "*t", 86400 ) );
local t2 = os.time( os.date( "!*t", 86400 ) );
print( t1, t2, t1 - t2 );
local t1 = os.date( "*t" );
local t2 = os.date( "!*t" );
print( t1.hour, t1.isdst, t2.hour, t2.isdst );
print( ((t1.hour - t2.hour) * 60 + (t1.min - t2.min)) * 60 );
产生输出:
1496733916 1496730316 3600
1496733916 1496730316 3600
06/06/17 09:25:16 06/06/17 07:25:16
86400 82800 3600
9 true 7 false
7200
现在我位于UTC + 2(目前由于夏季时间,冬季是UTC + 1,CEST)所以我预计会看到7200秒的偏移。然而,前两次尝试应该是等同的,它们是;给我一个小时的差异。当以人类可读格式打印时间时,可以清楚地看到两者之间的偏移是2小时。第四次尝试使用固定时间点(一天中86400秒,来自this question的技术)偏移量也是1小时)。最后直接直接减去小时数(以及在不是整个小时偏移的情况下的分钟数),我得到2小时的偏差。
我怀疑这是夏令时或dst造成的。我想要完成的是从时间戳(已经是UTC)中获取时间,并且由于os.time
是在本地时间,我需要转换该时间戳,使其与本地时间匹配。
或者我完全错过了什么?
答案 0 :(得分:0)
我认为差异来自于os.time()
如何读取由os.date('*t')
创建的表格,特别是其isdst
(夏令时)字段。
考虑这个例子:
tstamp = os.date('*t')
>> {day = 24,
hour = 10,
isdst = true,
min = 39,
month = 7,
sec = 31,
wday = 2,
yday = 205,
year = 2017}
os.date('%c', os.time(tstamp))
>> "Mon Jul 24 10:39:31 2017"
tstamp.isdst = false
os.date('%c', os.time(tstamp))
>> "Mon Jul 24 11:39:31 2017"
对不起,如果我说明显而易见的话。
答案 1 :(得分:0)
如the manual中所述,您不应直接使用os.time()
的结果,因为它可以是任何值。使用os.date()
从中获取一些有意义的信息。
在少数几个系统中,它仅具有任何已知的含义,即使这样,它也仅定义为自某个日期以来的秒数。
话虽如此,您遇到此问题的原因似乎是您的表设置了isdst
标志的事实。这意味着os.time()
将自动从中减去一个小时,因此您又回到了冬天。
顺便说一句,您的最后一个方法也被窃听了,因为它无法在午夜之前的小时工作,因为第二天已经有一个时间戳,所以小时字段的差异不再起作用。 / p>
做到这一点的正确方法非常简单:
local timezone = os.date('%z') -- "+0200"
local signum, hours, minutes = timezone:match '([+-])(%d%d)(%d%d)'
print(signum, hours, minutes)
local dt = (tonumber(signum..hours)*3600 + tonumber(signum..minutes)*60)
print(dt, type(dt))
哪些印刷品:
+ 02 00
7200 number