如何在lua中更新时间以反映执行期间的系统时区变化? 问题

如何在lua中更新时间以反映执行期间的系统时区变化? 问题,lua,timezone,awesome-wm,Lua,Timezone,Awesome Wm,我想修改awesome wm中的可怕的.widget.textclock小部件,以立即反映系统时区的变化。这个小部件和所有很棒的wm配置都是用lua编写的 当前,如果更改了系统时区,小部件将根据运行时设置的时区继续显示时间。小部件使用os.time函数检索时间,但这与系统时间不匹配 解决方案如下所示 lua脚本: local tz=require"luatz"; require "luatz.tzcache".clear_tz_cache() print("Before Changes (A

我想修改awesome wm中的
可怕的.widget.textclock
小部件,以立即反映系统时区的变化。这个小部件和所有很棒的wm配置都是用lua编写的

当前,如果更改了系统时区,小部件将根据运行时设置的时区继续显示时间。小部件使用
os.time
函数检索时间,但这与系统时间不匹配


解决方案如下所示 lua脚本:

local tz=require"luatz";

require "luatz.tzcache".clear_tz_cache()
print("Before Changes (America/Los_Angeles)")
print(os.date("!%H:%M",tz.time_in()))

os.execute("timedatectl set-timezone America/Chicago")

require "luatz.tzcache".clear_tz_cache()
print("America/Chicago")
print(os.date("!%H:%M",tz.time_in()))

os.execute("timedatectl set-timezone America/New_York")
require "luatz.tzcache".clear_tz_cache()

print("America/New_York")
print(os.date("!%H:%M",tz.time_in()))
local tz=require"luatz";

require "luatz.tzcache".clear_tz_cache()
print("Before Changes (America/Los_Angeles)")
print(os.date("%H:%M",tz.time_in()))

os.execute("timedatectl set-timezone America/Chicago")

require "luatz.tzcache".clear_tz_cache()
print("America/Chicago")
print(os.date("%H:%M",tz.time_in()))

os.execute("timedatectl set-timezone America/New_York")
require "luatz.tzcache".clear_tz_cache()

print("America/New_York")
print(os.date("%H:%M",tz.time_in()))
输出:

Before Changes (America/Los_Angeles)
15:33
America/Chicago
17:33
America/New_York
18:33
Before Change - System TZ is 
America/Los_Angeles

os.time(): 11:54
luatz.time(): 11:54
gettime..gettime(): 11:54

Time zone changed to America/New_York

After  Change - System TZ is 
America/New_York

os.time(): 11:54
luatz.time(): 11:54
gettime.gettime(): 11:54

变通办法 这可以通过重新启动awesome窗口管理器来解决,这会使小部件再次获得正确的时区。当然,如果时区发生变化,则需要重新启动窗口管理器

所需的效果是,当时区定期或每次调用
os.time
函数时,从系统更新时区


用例 如果你好奇的话,这个用例就在笔记本电脑上。我经常出差,在
systemd定时器上运行
tzupdate
。我想自动改变我的时区。除了实际显示时间的小部件没有注意到系统时区的变化之外,这工作正常


到目前为止已经试过了
  • 取消设置“$TZ”环境变量。但是ArchLinux从一开始就没有设置这个变量,所以我不确定lua是如何确定正确的时区的
  • 使用
    luatz
    库,特别是
    tzcache.clear_tz_cache()
    函数。这似乎没有效果
  • 使用函数而不是
    os.time()
    luatz.time()
    luatz.gettime.gettime()
    检索系统时间。这些函数与其他函数的检索时间相同
  • 使用
    luatz.time\u in()
    函数,但这将返回时区偏移应用于UTC时间两次的时间
    luatz.time()
    返回正确的本地时间,但应返回UTC时间

  • 更新的luatz
    
    我尝试按照建议使用
    luatz
    库,但它似乎没有重新检查系统时区,即使在调用
    tzcache.clear_tz_cache()
    函数之后也是如此

    我克隆了
    luatz
    repo并将
    luatz
    复制到系统模块目录中。脚本似乎加载正确,但未更改忽略系统时区更改的效果。据我所知,这与
    os.time()
    函数没有任何区别

    luatz测试脚本:

    local luatz = require "luatz"
    local tzcache = require "luatz.tzcache"
    local gettime = require "luatz.gettime"
    
    print ("\nBefore Change - System TZ is ")
    os.execute("timedatectl | grep 'Time zone' | awk '{ print $3 }'")
    print("\nos.time(): "..os.date("%H:%M", os.time()))
    print("luatz.time(): "..os.date("%H:%M", luatz.time()))
    print("gettime..gettime(): "..os.date("%H:%M", gettime.gettime()))
    
    print("\nTime zone changed to America/New_York")
    os.execute("timedatectl set-timezone America/New_York")
    
    tzcache.clear_tz_cache()
    
    print ("\nAfter  Change - System TZ is ")
    os.execute("timedatectl | grep 'Time zone' | awk '{ print $3 }'")
    print ("\nos.time(): "..os.date("%H:%M", os.time()))
    print ("luatz.time(): "..os.date("%H:%M", luatz.time()))
    print("gettime.gettime(): "..os.date("%H:%M", gettime.gettime()))
    
    输出:

    Before Changes (America/Los_Angeles)
    15:33
    America/Chicago
    17:33
    America/New_York
    18:33
    
    Before Change - System TZ is 
    America/Los_Angeles
    
    os.time(): 11:54
    luatz.time(): 11:54
    gettime..gettime(): 11:54
    
    Time zone changed to America/New_York
    
    After  Change - System TZ is 
    America/New_York
    
    os.time(): 11:54
    luatz.time(): 11:54
    gettime.gettime(): 11:54
    

    luatz.time\u in()
    因此,
    luatz.time_in()
    函数确实会随着系统时区的变化而更新,我对此感到兴奋!但是,
    time\u in()
    不显示正确的本地时间。它将时区偏移量添加到正确的本地时间,导致时间延迟数小时。我尝试设置
    TZ
    环境变量,但没有效果。出于某种原因,
    luatz.time()
    正在返回本地时间,
    luatz.time\u in()
    正在返回两次应用时区偏移的结果

    lua脚本:

    local tz=require"luatz";
    
    require "luatz.tzcache".clear_tz_cache()
    print("Before Changes (America/Los_Angeles)")
    print(os.date("!%H:%M",tz.time_in()))
    
    os.execute("timedatectl set-timezone America/Chicago")
    
    require "luatz.tzcache".clear_tz_cache()
    print("America/Chicago")
    print(os.date("!%H:%M",tz.time_in()))
    
    os.execute("timedatectl set-timezone America/New_York")
    require "luatz.tzcache".clear_tz_cache()
    
    print("America/New_York")
    print(os.date("!%H:%M",tz.time_in()))
    
    local tz=require"luatz";
    
    require "luatz.tzcache".clear_tz_cache()
    print("Before Changes (America/Los_Angeles)")
    print(os.date("%H:%M",tz.time_in()))
    
    os.execute("timedatectl set-timezone America/Chicago")
    
    require "luatz.tzcache".clear_tz_cache()
    print("America/Chicago")
    print(os.date("%H:%M",tz.time_in()))
    
    os.execute("timedatectl set-timezone America/New_York")
    require "luatz.tzcache".clear_tz_cache()
    
    print("America/New_York")
    print(os.date("%H:%M",tz.time_in()))
    
    输出:

    Before Changes (America/Los_Angeles)
    08:59
    America/Chicago
    10:59
    America/New_York
    11:59
    

    实际系统本地时间:
    15:59

    后面的低级函数“就好像调用了一样,
    tzset
    使用环境变量
    TZ
    来确定时区,如果不存在,则从
    /etc/localtime
    读取

    环境变量主要是在程序启动前确定的,因此,要使时区发生变化,您可以找到一种方法来设置
    TZ
    变量。一个
    os.setenv
    可以通过几个lua库获得,例如

    如果这似乎不是一个合理的操作过程,那么您可以确保您的脚本在没有设置
    TZ
    的情况下启动;这将强制
    tzset
    /etc/localtime
    读取。不幸的是,大多数时候这个文件都被缓存了,你不会得到更新;这取决于您的系统


    或者,您可以使用不同的库来获取时间,而不是
    os
    库。在中,您可以使用
    要求“luatz.tzcache”清除其时区缓存。清除\u tz_cache()
    ,您可以在获取时间之前调用此函数。

    我正在运行arch linux,它尚未设置tz环境变量
    echo$TZ
    在命令行中不返回任何内容,因此我不确定这是否是一个选项。我将查看
    luatz
    luatz
    函数也会继续返回不正确的系统时间,即使在清除
    tzcache
    luatz.time()
    是UTC时间
    luatz.time_in()
    是本地时间。尝试以下代码:我尝试了
    luatz.time\u in()
    ,虽然它会随着系统时区的变化而变化,但不会报告正确的本地时间。有什么想法吗?
    os.date
    添加当前系统时区偏移量<代码>中的时间已为您调整。在日期格式字符串前面加上
    以防止出现这种情况<代码>打印(操作系统日期(“!%H:%M”,tz.time\u in())