【问题标题】:Find out timezone offset找出时区偏移
【发布时间】:2017-11-07 02:57:15
【问题描述】:

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

还是我完全错过了什么?

【问题讨论】:

  • 也许我给here的回答会对你有所帮助
  • 感谢您的评论。我也考虑过,但是我不想假设 dst 是 +1 小时,如您的链接中所述,某些国家/地区可能有 30 分钟
  • @JavierMr - 在that 答案中计算zone_diff(以秒为单位)的方法确实不正确。现在已经修复了。

标签: date lua timezone dst


【解决方案1】:

正如the manual 中所述,您不应该直接使用os.time() 的结果,因为它可以是任何值。使用os.date() 从中获取一些有意义的信息。

它仅在少数系统中具有任何已知含义,即使如此,它也仅定义为自某个日期以来的秒数。

话虽如此,您遇到此问题的原因似乎是您的表设置了isdst 标志。这意味着os.time() 会自动减去一个小时,所以你又回到了冬天。

顺便说一句,你的最后一种方法也有问题,因为它在午夜之前的几个小时内不起作用,其中一个时间戳已经在第二天,所以小时字段的差异不再起作用。

执行此操作的正确方法非常简单:

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

【讨论】:

    【解决方案2】:

    我认为差异来自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"
    

    不过,如果我说的很明显,我很抱歉。

    【讨论】:

      猜你喜欢
      • 2017-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多