Проблема
Я хочу изменить виджет awful.widget.textclock
в awesome-wm, чтобы он немедленно отражал изменение системного часового пояса. Этот виджет и весь конфиг awesome-wm написаны на lua.
В настоящее время, если системный часовой пояс изменен, виджет продолжает отображать время в соответствии с часовым поясом, установленным во время выполнения. Виджет использует функцию os.time
для получения времени, но это не соответствует системному времени.
Решение, как показано ниже
луа скрипт:
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
Обходной путь
Это можно решить, перезапустив удивительный оконный менеджер, из-за чего виджет снова получает правильный часовой пояс. Естественно, при изменении часового пояса требуется еще один перезапуск оконного менеджера.
Желаемый эффект заключается в обновлении часового пояса из системы при его изменении либо периодически, либо при каждом вызове функции os.time
.
Пример использования
Если вам интересно, вариант использования для этого на ноутбуке. Я часто путешествую и езжу tzupdate
на systemd timer
. Я хотел бы автоматизировать смену часового пояса. Это отлично работает, за исключением того, что виджет, который фактически отображает время, не замечает изменения системного часового пояса.
Пытался до сих пор
- Сбросьте переменную окружения $TZ. Но Arch Linux никогда не устанавливает эту переменную в первую очередь, поэтому я не уверен, как lua вообще определяет правильный часовой пояс.
- Используйте библиотеку
luatz
и, в частности, функциюtzcache.clear_tz_cache()
. Кажется, это не имеет никакого эффекта. - Получить системное время с помощью функций, отличных от
os.time()
:luatz.time()
иluatz.gettime.gettime()
. Они извлекают то же время, что и другие функции. - Используйте функцию
luatz.time_in()
, но она возвращает время со смещением часового пояса, примененным дважды ко времени UTC.luatz.time()
возвращает правильное местное время, но должно возвращать время UTC.
ОБНОВЛЕНО luatz
Я попытался возиться с библиотекой luatz
в соответствии с рекомендациями, но, похоже, она не перепроверяет системный часовой пояс даже после вызова функции tzcache.clear_tz_cache()
.
Я клонировал репозиторий luatz
и скопировал luatz
в каталог системных модулей. Скрипт вроде загружается корректно, но не изменился эффект игнорирования изменения системного часового пояса. Насколько я могу судить, это ничем не отличается от функции os.time()
.
тестовый сценарий луатца:
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()
возвращает результат двойного применения смещения часового пояса.
луа скрипт:
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
.