Skip to content

Commit

Permalink
fix: fall back to UTC if localzone() fails (#7)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
mortenpi authored Jun 26, 2023
1 parent f530d11 commit dd354c1
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 8 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

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).

## Unreleased
## Version v0.1.2 - 2023-06-26

### Fixed

* If TimeZones.jl fails to determine the system's timezone, JuliaHub.jl now gracefully falls back to UTC to represent dates and times. (#7)

## Version v0.1.1 - 2023-06-24

### Added

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "JuliaHub"
uuid = "bc7fa6ce-b75e-4d60-89ad-56c957190b6e"
authors = ["JuliaHub Inc."]
version = "0.1.1"
version = "0.1.2"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
2 changes: 2 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using JuliaHub
using Documenter, DocumenterMermaid
import TimeZones

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

DocMeta.setdocmeta!(
JuliaHub, :DocTestSetup,
Expand Down
9 changes: 9 additions & 0 deletions src/JuliaHub.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import TOML
import URIs
import UUIDs

const _LOCAL_TZ = Ref{Dates.TimeZone}()

include("utils.jl")
include("authentication.jl")
include("restapi.jl")
Expand All @@ -28,4 +30,11 @@ include("jobs/logging.jl")
include("jobs/logging-kafka.jl")
include("jobs/logging-legacy.jl")

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

end
16 changes: 14 additions & 2 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ end
_utc2localtz(timestamp::Number) = _utc2localtz(Dates.unix2datetime(timestamp))
function _utc2localtz(datetime_utc::Dates.DateTime)::TimeZones.ZonedDateTime
datetimez_utc = TimeZones.ZonedDateTime(datetime_utc, TimeZones.tz"UTC")
return TimeZones.astimezone(datetimez_utc, TimeZones.localzone())
return TimeZones.astimezone(datetimez_utc, _LOCAL_TZ[])
end
# Special version of _utc2localtz to handle integer ms timestamp
function _ms_utc2localtz(timestamp::Integer)::TimeZones.ZonedDateTime
Expand Down Expand Up @@ -397,5 +397,17 @@ function _parse_tz(timestamp_str::AbstractString; msg::Union{AbstractString, Not
end
throw(JuliaHubError(errmsg))
end
return TimeZones.astimezone(timestamp, TimeZones.localzone())
return TimeZones.astimezone(timestamp, _LOCAL_TZ[])
end

# It's quite easy to make TimeZones.localzone() fail and throw.
# So this wraps it, and adds a UTC fallback (which seems like the sensible
# default) in the case where somehow the local timezone is not configured properly.
function _localtz()
try
TimeZones.localzone()
catch e
@debug "Unable to determine local timezone" exception = (e, catch_backtrace())
TimeZones.tz"UTC"
end
end
9 changes: 5 additions & 4 deletions test/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,26 @@ end
end

@testset "_parse_tz" begin
@test isassigned(JuliaHub._LOCAL_TZ)
let t = JuliaHub._parse_tz("2022-10-12T05:30:31.1+00:00")
@test t isa TimeZones.ZonedDateTime
@test t.timezone == TimeZones.localzone()
@test t.timezone == JuliaHub._LOCAL_TZ[]
@test Dates.millisecond(t) == 100
end
let t = JuliaHub._parse_tz("2022-10-12T05:30:31.12+00:00")
@test t isa TimeZones.ZonedDateTime
@test t.timezone == TimeZones.localzone()
@test t.timezone == JuliaHub._LOCAL_TZ[]
@test Dates.millisecond(t) == 120
end
let t = JuliaHub._parse_tz("2022-10-12T05:30:31.123+00:00")
@test t isa TimeZones.ZonedDateTime
@test t.timezone == TimeZones.localzone()
@test t.timezone == JuliaHub._LOCAL_TZ[]
@test Dates.millisecond(t) == 123
end
@test_throws JuliaHub.JuliaHubError JuliaHub._parse_tz("2022-10-12T05:30:31.+00:00")
let t = JuliaHub._parse_tz("2022-10-12T05:30:31+00:00")
@test t isa TimeZones.ZonedDateTime
@test t.timezone == TimeZones.localzone()
@test t.timezone == JuliaHub._LOCAL_TZ[]
@test Dates.millisecond(t) == 0
end
@test_throws JuliaHub.JuliaHubError JuliaHub._parse_tz("")
Expand Down

0 comments on commit dd354c1

Please sign in to comment.