gpt4 book ai didi

lua - 如何更新lua中的时间以反射(reflect)执行期间系统时区的变化?

转载 作者:行者123 更新时间:2023-12-04 21:54:47 25 4
gpt4 key购买 nike

问题

我想修改 awesome-wm 中的 awful.widget.textclock 小部件以立即反射(reflect)系统时区的变化。这个小部件和所有 awesome-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()))

输出:

Before Changes (America/Los_Angeles)
15:33
America/Chicago
17:33
America/New_York
18:33

解决方法

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

期望的效果是在系统更改时更新时区,可以是定期更新,也可以是每次调用 os.time 函数时更新。


用例

如果您好奇的话,这个用例是在笔记本电脑上。我经常出差并在 systemd timer 上运行 tzupdate。我想自动更改我的时区。这工作正常,只是实际显示时间的小部件没有注意到系统时区的变化。


到目前为止已经尝试过

  1. 取消设置“$TZ”环境变量。但是 Arch Linux 从一开始就不会设置这个变量,所以我不确定 lua 是如何确定正确的时区的。
  2. 使用luatz 库,特别是tzcache.clear_tz_cache() 函数。这似乎没有效果。
  3. 使用 os.time() 以外的函数获取系统时间:luatz.time()luatz.gettime.gettime()。这些函数与其他函数同时检索。
  4. 使用 luatz.time_in() 函数,但这会返回时区偏移应用两次 UTC 时间的时间。 luatz.time() 返回正确的本地时间,但应该返回 UTC 时间。

更新 luatz

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

我克隆了 luatz 存储库并将 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 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_in()

所以 luatz.time_in() 函数会随着系统时区的变化而更新,我对此感到很兴奋!但是,time_in() 不显示正确的本地时间。它将时区偏移量添加到正确的本地时间,导致时间晚了几个小时。我尝试设置 TZ 环境变量,但这没有效果。出于某种原因,luatz.time() 返回本地时间,而 luatz.time_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()))

输出:

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

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

最佳答案

os.date 背后的底层函数, localtime(3) “就像它调用了 tzset(3) 一样,tzset 使用环境变量 TZ 来确定时区,如果不存在,则从 /中读取etc/localtime.

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

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

或者,您可以使用不同的库来获取时间,而不是 os 库。在 luatz您可以使用 require "luatz.tzcache".clear_tz_cache() 清除它的时区缓存,您可以在获取时间之前调用此函数。

关于lua - 如何更新lua中的时间以反射(reflect)执行期间系统时区的变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25212106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com