Open cppcoffee opened 1 year ago
Yes -- there are two parts to this that are platform specific: (1) how to find out which timezone has been configured, (2) the timezone offsets to use for that timezone. (1) seems to be the issue here -- chrono relies on the iana-time-zone crate for this, please file an issue there.
@cppcoffee Is there a not-too-difficult way for me to test chrono on openwrt?
Hi @pitdicker , OpenWrt has virtualization image that you can try.
Okay, I can reproduce it.
docker import http://downloads.openwrt.org/attitude_adjustment/12.09/x86/generic/openwrt-x86-generic-rootfs.tar.gz openwrt-x86-generic-rootfs
rustup target add x86_64-unknown-linux-musl
docker run -v $(pwd)/target/x86_64-unknown-linux-musl:/target -i openwrt-x86-generic-rootfs /target/debug/deps/chrono-f094327353343c38
Our test suite fails with:
failures:
---- offset::local::tz_info::timezone::tests::test_time_zone_from_posix_tz stdout ----
Error: ParseInt(ParseIntError { kind: Empty })
failures:
offset::local::tz_info::timezone::tests::test_time_zone_from_posix_tz
The docker image has no timezone files and /etc/TZ
is a dangling pointer. Maybe timezone support has to be installed first?
On my openwrt environment, the /etc/TZ
file content as follows:
# cat /etc/TZ
CST-8
OpenWrt commands for setting the time:
$ uci get system.@system[0].timezone
$ uci set system.@system[0].timezone='Asia/Shanghai'
$ uci commit system
$ /etc/init.d/system reload
$ date
The iana-time-zone crate support OpenWrt now:
https://github.com/strawlab/iana-time-zone/pull/109
Use chrono + iana-time-zone new version, chrono::Local
prints out UTC time.
https://github.com/strawlab/iana-time-zone/pull/109#issuecomment-1579975176
I suppose that would be because the time zone info files aren't found in the places where they are stored on conventional Linux systems.
Where chrono to find the time zone info files?
On OpenWrt print chrono::Local::now()
, without TZ
env, output UTC time.
$ ./chrono-demo-uclibc
2023-06-17T03:44:47.615484252+00:00
If use TZ=CST-8
env, output local time.
$ cat /etc/TZ
CST-8
$ TZ=CST-8 ./chrono-demo-uclibc
2023-06-17T11:44:12.281978327+08:00
Maybe I should try installing the timezone package.
In my scenario, it was solved by manually setting the TZ
environment:
fn main() {
let tz = std::fs::read_to_string("/etc/TZ").unwrap_or("CST-8".to_owned());
std::env::set_var("TZ", tz);
// do something
}
I got the same issue, and solve by set TZ env I hve tried golang for test, golang seems get right output time
To solve this we need to know what OpenWRT does that is different from regular Linux distributions. Can someone provide the following information?
TZ
variable/etc/localtime
link to?/usr/share/lib/zoneinfo
)?The OpenWrt os-release content:
root@OpenWrt:/# cat /etc/os-release
NAME="OpenWrt"
VERSION="22.03.4"
ID="openwrt"
ID_LIKE="lede openwrt"
PRETTY_NAME="OpenWrt 22.03.4"
VERSION_ID="22.03.4"
HOME_URL="https://openwrt.org/"
BUG_URL="https://bugs.openwrt.org/"
SUPPORT_URL="https://forum.openwrt.org/"
BUILD_ID="20231016-1458-g9191cfc-dirty"
OPENWRT_BOARD="ramips/mt7621"
OPENWRT_ARCH="mipsel_24kc"
OPENWRT_TAINTS="no-all busybox"
OPENWRT_DEVICE_MANUFACTURER="OpenWrt"
OPENWRT_DEVICE_MANUFACTURER_URL="https://openwrt.org/"
OPENWRT_DEVICE_PRODUCT="Generic"
OPENWRT_DEVICE_REVISION="v0"
OPENWRT_RELEASE="OpenWrt 22.03.4 20231016-1458-g9191cfc-dirty"
The OpenWrt TZ
file location /tmp/TZ
:
root@OpenWrt:/# ll /tmp/TZ
-rw-r--r-- 1 root root 4 Apr 9 12:30 /tmp/TZ
root@OpenWrt:/# cat /tmp/TZ
UTC
The /tmp/TZ
build on:
/etc/init.d/system:24: echo "$timezone" > /tmp/TZ
The /etc/init.d/system
content:
root@OpenWrt:/# cat /etc/init.d/system
#!/bin/sh /etc/rc.common
# Copyright (C) 2014 OpenWrt.org
START=10
USE_PROCD=1
validate_system_section() {
uci_load_validate system system "$1" "$2" \
'hostname:string:OpenWrt' \
'conloglevel:uinteger' \
'buffersize:uinteger' \
'timezone:string:UTC' \ # load TZ variable to timezone
'zonename:string'
}
system_config() {
[ "$2" = 0 ] || {
echo "validation failed"
return 1
}
echo "$hostname" > /proc/sys/kernel/hostname
[ -z "$conloglevel" -a -z "$buffersize" ] || dmesg ${conloglevel:+-n $conloglevel} ${buffersize:+-s $buffersize}
echo "$timezone" > /tmp/TZ
[ -n "$zonename" ] && [ -f "/usr/share/zoneinfo/${zonename// /_}" ] \
&& ln -sf "/usr/share/zoneinfo/${zonename// /_}" /tmp/localtime \
&& rm -f /tmp/TZ
# apply timezone to kernel
hwclock -u --systz
}
reload_service() {
config_load system
config_foreach validate_system_section system system_config
}
service_triggers() {
procd_add_reload_trigger "system"
procd_add_validation validate_system_section
}
start_service() {
reload_service
}
system config:
root@OpenWrt:/# cat /etc/config/system
config system
option hostname 'OpenWrt'
option timezone 'UTC' # the origin timezone
option ttylogin '0'
option log_size '64'
option urandom_seed '0'
option compat_version '1.1'
config timeserver 'ntp'
option enabled '1'
option enable_server '0'
list server '0.openwrt.pool.ntp.org'
list server '1.openwrt.pool.ntp.org'
list server '2.openwrt.pool.ntp.org'
list server '3.openwrt.pool.ntp.org'
System configuration /etc/config/system:
https://openwrt.org/docs/guide-user/base-system/system_configuration
Rust example code:
On ubuntu output:
On openwrt output:
Openwrt timezone config:
Expected openwrt output +08:00
Is it possible that chrono::Local does not support openwrt systems? It prints out as utc。