找出时区偏移

时间:2017-06-06 07:43:00

标签: date lua timezone dst

我希望找到使用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是在本地时间,我需要转换该时间戳,使其与本地时间匹配。

或者我完全错过了什么?

2 个答案:

答案 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