Kotlin / kotlinx-datetime

KotlinX multiplatform date/time library
Apache License 2.0
2.42k stars 102 forks source link

Permit missing /etc/localtime #426

Closed dkhalanskyjb closed 3 months ago

dkhalanskyjb commented 3 months ago

We received a report that in some container images, /etc/localtime is left unspecified. According to the Linux documentation (https://www.man7.org/linux/man-pages/man5/localtime.5.html), this means that the UTC time zone must be used.

We still throw an exception if we see a time zone we don't recognize.

ArtRoman commented 2 months ago

Hello. It still fails on Ubuntu ARM 20.04:

roman@ubuntum1:~$ '/media/psf/Home/Downloads/app.kexe' 
Uncaught Kotlin exception: kotlin.native.internal.FileFailedToInitializeException: There was an error during file or class initialization
    at 0   app.kexe                            0x3e286b           ThrowFileFailedToInitializeException + 235 (/opt/buildAgent/work/ed783494cd2364bc/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt:134:15)
    at 1   app.kexe                            0xcb61ab           CallInitGlobalPossiblyLock + 735 
    at 2   app.kexe                            0x7eb4b7           kfun:com.shared.dataTypes.CrossDateTime#<get-$companion>#static(){}com.shared.dataTypes.CrossDateTime.Companion + 71 (/Users/roman/Documents/Develop/Client-Multiplatform/app/src/commonMain/kotlin/com/shared/dataTypes/CrossDateTime.kt:1:1)
    …
    at 7   app.kexe                            0xbfe5d7           Konan_start + 119 (/Users/roman/Documents/Develop/Client-Multiplatform/app/src/linuxMain/kotlin/com/LinuxMain.kt:205:1)
    at 8   app.kexe                            0xc9fb57           Init_and_run_start + 99 
    at 9   libc.so.6                           0xffffbf05008f     __libc_start_main + 231 
    at 10  app.kexe                            0x3ae847           0x0 + 3860551 (../sysdeps/aarch64/start.S:83:0)
Caused by: kotlinx.datetime.IllegalTimeZoneException: Could not determine the timezone ID that `/etc/localtime` corresponds to
    at 0   app.kexe                            0x78b8f7           kfun:kotlinx.datetime.internal#currentSystemDefaultZone(){}kotlin.Pair<kotlin.String,kotlinx.datetime.internal.TimeZoneRules?> + 567 (/Users/roman/.gradle/daemon/8.7/Z:/BuildAgent/work/8ebe0a8279b7bad8/core/linux/src/internal/TimeZoneNative.kt:18:18)
    at 1   app.kexe                            0x798bef           kfun:kotlinx.datetime.TimeZone.Companion#currentSystemDefault(){}kotlinx.datetime.TimeZone + 159 (/Users/roman/.gradle/daemon/8.7/Z:/BuildAgent/work/8ebe0a8279b7bad8/core/native/src/TimeZone.kt:23:33)
…

The line is private var localTz: TimeZone = TimeZone.currentSystemDefault()

So I must use private var localTz: TimeZone = runCatching { TimeZone.currentSystemDefault() }.getOrNull() ?: TimeZone.UTC to avoid crashing.

The '/etc/localtime' file exists (it's not a symlink):

roman@ubuntum1:~$ file /etc/localtime
/etc/localtime: timezone data, version 2, 7 gmt time flags, 7 std time flags, no leap seconds, 121 transition times, 7 abbreviation chars

roman@ubuntum1:~$ uname -a
Linux ubuntum1 5.4.0-70-generic #78-Ubuntu SMP Fri Mar 19 13:29:32 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux

roman@ubuntum1:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.2 LTS
Release:    20.04
Codename:   focal

Why the localtime file can be not readable?

dkhalanskyjb commented 2 months ago

@ArtRoman, it's because /etc/localtime can either be absent or a symlink, it can't be a regular file. See https://www.man7.org/linux/man-pages/man5/localtime.5.html :

Because the timezone identifier is extracted from the symlink target name of /etc/localtime, this file may not be a normal file or hardlink.

ArtRoman commented 2 months ago

@dkhalanskyjb I've checked some of Ubuntu versions.

It's a regular file in Ubuntu 20.04 ARM: Screenshot 2024-08-30 at 18 07 58

It's a regular file in Ubuntu 22.04 ARM: Screenshot 2024-08-30 at 18 19 06

But it's a symlink in Ubuntu 24.04 ARM: Screenshot 2024-08-30 at 19 26 31

And it's also a symlink in Ubuntu 24.04 X64: Screenshot 2024-08-30 at 18 08 50

So, it's like a version-specific thing.

dkhalanskyjb commented 2 months ago

@ArtRoman, thanks, filed https://github.com/Kotlin/kotlinx-datetime/issues/430.