Skip to content

Commit dd354c1

Browse files
authored
fix: fall back to UTC if localzone() fails (#7)
* fix: fall back to UTC if localzone fails * move _localtz into a separate function * add changelog, set version to 0.1.2 * fix doctest env
1 parent f530d11 commit dd354c1

6 files changed

Lines changed: 38 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22

33
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
44

5-
## Unreleased
5+
## Version v0.1.2 - 2023-06-26
6+
7+
### Fixed
8+
9+
* If TimeZones.jl fails to determine the system's timezone, JuliaHub.jl now gracefully falls back to UTC to represent dates and times. (#7)
10+
11+
## Version v0.1.1 - 2023-06-24
612

713
### Added
814

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "JuliaHub"
22
uuid = "bc7fa6ce-b75e-4d60-89ad-56c957190b6e"
33
authors = ["JuliaHub Inc."]
4-
version = "0.1.1"
4+
version = "0.1.2"
55

66
[deps]
77
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

docs/make.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using JuliaHub
22
using Documenter, DocumenterMermaid
3+
import TimeZones
34

45
# Timestamp printing is dependent on the timezone, so we force a specific (non-UTC)
56
# timezone to make sure that the doctests don't fail because of timezone differences.
67
ENV["TZ"] = "America/New_York"
8+
JuliaHub._LOCAL_TZ[] = TimeZones.localzone()
79

810
DocMeta.setdocmeta!(
911
JuliaHub, :DocTestSetup,

src/JuliaHub.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import TOML
1313
import URIs
1414
import UUIDs
1515

16+
const _LOCAL_TZ = Ref{Dates.TimeZone}()
17+
1618
include("utils.jl")
1719
include("authentication.jl")
1820
include("restapi.jl")
@@ -28,4 +30,11 @@ include("jobs/logging.jl")
2830
include("jobs/logging-kafka.jl")
2931
include("jobs/logging-legacy.jl")
3032

33+
function __init__()
34+
# We'll only attempt to determine the local timezone once, when the package loads,
35+
# and store the result in a global. This way all timestamps will have consistent timezones
36+
# even if something in the environment changes.
37+
_LOCAL_TZ[] = _localtz()
38+
end
39+
3140
end

src/utils.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ end
350350
_utc2localtz(timestamp::Number) = _utc2localtz(Dates.unix2datetime(timestamp))
351351
function _utc2localtz(datetime_utc::Dates.DateTime)::TimeZones.ZonedDateTime
352352
datetimez_utc = TimeZones.ZonedDateTime(datetime_utc, TimeZones.tz"UTC")
353-
return TimeZones.astimezone(datetimez_utc, TimeZones.localzone())
353+
return TimeZones.astimezone(datetimez_utc, _LOCAL_TZ[])
354354
end
355355
# Special version of _utc2localtz to handle integer ms timestamp
356356
function _ms_utc2localtz(timestamp::Integer)::TimeZones.ZonedDateTime
@@ -397,5 +397,17 @@ function _parse_tz(timestamp_str::AbstractString; msg::Union{AbstractString, Not
397397
end
398398
throw(JuliaHubError(errmsg))
399399
end
400-
return TimeZones.astimezone(timestamp, TimeZones.localzone())
400+
return TimeZones.astimezone(timestamp, _LOCAL_TZ[])
401+
end
402+
403+
# It's quite easy to make TimeZones.localzone() fail and throw.
404+
# So this wraps it, and adds a UTC fallback (which seems like the sensible
405+
# default) in the case where somehow the local timezone is not configured properly.
406+
function _localtz()
407+
try
408+
TimeZones.localzone()
409+
catch e
410+
@debug "Unable to determine local timezone" exception = (e, catch_backtrace())
411+
TimeZones.tz"UTC"
412+
end
401413
end

test/utils.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,26 @@ end
5252
end
5353

5454
@testset "_parse_tz" begin
55+
@test isassigned(JuliaHub._LOCAL_TZ)
5556
let t = JuliaHub._parse_tz("2022-10-12T05:30:31.1+00:00")
5657
@test t isa TimeZones.ZonedDateTime
57-
@test t.timezone == TimeZones.localzone()
58+
@test t.timezone == JuliaHub._LOCAL_TZ[]
5859
@test Dates.millisecond(t) == 100
5960
end
6061
let t = JuliaHub._parse_tz("2022-10-12T05:30:31.12+00:00")
6162
@test t isa TimeZones.ZonedDateTime
62-
@test t.timezone == TimeZones.localzone()
63+
@test t.timezone == JuliaHub._LOCAL_TZ[]
6364
@test Dates.millisecond(t) == 120
6465
end
6566
let t = JuliaHub._parse_tz("2022-10-12T05:30:31.123+00:00")
6667
@test t isa TimeZones.ZonedDateTime
67-
@test t.timezone == TimeZones.localzone()
68+
@test t.timezone == JuliaHub._LOCAL_TZ[]
6869
@test Dates.millisecond(t) == 123
6970
end
7071
@test_throws JuliaHub.JuliaHubError JuliaHub._parse_tz("2022-10-12T05:30:31.+00:00")
7172
let t = JuliaHub._parse_tz("2022-10-12T05:30:31+00:00")
7273
@test t isa TimeZones.ZonedDateTime
73-
@test t.timezone == TimeZones.localzone()
74+
@test t.timezone == JuliaHub._LOCAL_TZ[]
7475
@test Dates.millisecond(t) == 0
7576
end
7677
@test_throws JuliaHub.JuliaHubError JuliaHub._parse_tz("")

0 commit comments

Comments
 (0)