Skip to content

Commit

Permalink
Merge pull request #19 from JuliaTime/rf/utcdatetimes
Browse files Browse the repository at this point in the history
Adding support for UTCDateTime conversions
  • Loading branch information
rofinn committed Feb 24, 2023
2 parents a92bc93 + e497686 commit c8c5e28
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 5 deletions.
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
name = "LaxZonedDateTimes"
uuid = "e4c54217-8d3e-5504-a69c-0db1bad43e12"
authors = ["Invenia Technical Computing"]
version = "1.3.1"
version = "1.4.0"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Intervals = "d8418881-c3e1-53bb-8760-2df7ec849ed5"
TimeZones = "f269a46b-ccf7-5d73-abea-4c690281aa53"
UTCDateTimes = "0f7cfa37-7abf-4834-b969-a8aa512401c2"

[compat]
Intervals = "1.5"
TimeZones = "0.11, 1"
UTCDateTimes = "1.1"
julia = "1"

[extras]
Expand Down
14 changes: 14 additions & 0 deletions src/LaxZonedDateTimes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ using Dates: AbstractDateTime, DatePeriod, DateTime, Dates, Millisecond, Period,
using Intervals
using TimeZones
using TimeZones: Local, UTC, interpret, timezone
using UTCDateTimes

export
LaxZonedDateTime, ZDT,
Expand Down Expand Up @@ -39,6 +40,11 @@ function LaxZonedDateTime()
LaxZonedDateTime(DateTime(0), utc, utc, false)
end

function LaxZonedDateTime(utcdt::UTCDateTime)
utc = tz"UTC"
LaxZonedDateTime(DateTime(utcdt), utc, utc, true)
end

function LaxZonedDateTime(zdt::ZonedDateTime)
LaxZonedDateTime(DateTime(zdt), timezone(zdt), zdt.zone, true)
end
Expand Down Expand Up @@ -210,6 +216,9 @@ Base.promote_rule(::Type{LaxZonedDateTime},::Type{ZonedDateTime}) = LaxZonedDate
Base.convert(::Type{LaxZonedDateTime}, x::ZonedDateTime) = LaxZonedDateTime(x)
Base.convert(::Type{ZonedDateTime}, x::LaxZonedDateTime) = ZonedDateTime(x)

Base.convert(::Type{LaxZonedDateTime}, x::UTCDateTime) = LaxZonedDateTime(x)
Base.convert(::Type{UTCDateTime}, x::LaxZonedDateTime) = UTCDateTime(x)

function Base.isless(a::LaxZonedDateTime, b::LaxZonedDateTime)
if !isrepresentable(a) || !isrepresentable(b)
return false
Expand Down Expand Up @@ -274,6 +283,11 @@ function TimeZones.ZonedDateTime(lzdt::LaxZonedDateTime, resolve_by::Symbol=:thr
end
end

# Not very performant, but just reuse the ZonedDateTime constructor above for UTCDateTimes
function UTCDateTimes.UTCDateTime(lzdt::LaxZonedDateTime, args...)
return UTCDateTime(ZonedDateTime(lzdt, args...))
end

const ZDT = Union{ZonedDateTime, LaxZonedDateTime}

include("accessors.jl")
Expand Down
57 changes: 53 additions & 4 deletions test/laxzoneddatetimes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
utc = TimeZone("UTC")
fixed = FixedTimeZone("UTC-06:00")
dt = DateTime(2016, 8, 11, 2, 30)
utcdt = UTCDateTime(dt)

@test ZonedDateTime(LaxZonedDateTime(utcdt)) == ZonedDateTime(utcdt)

for t in (utc, fixed)
@test ZonedDateTime(LaxZonedDateTime(dt, t)) == ZonedDateTime(dt, t)

for p in (Hour(1), Day(1))
@test LaxZonedDateTime(dt, t) + p == LaxZonedDateTime(dt + p, t)
@test LaxZonedDateTime(dt, t) - p == LaxZonedDateTime(dt - p, t)
Expand Down Expand Up @@ -55,7 +59,7 @@ end
@test isequal(non_existent - Hour(0), LaxZonedDateTime())

@test isequal((non_existent + Hour(1)) + Hour(1), LaxZonedDateTime())
@test isequal((non_existent + Hour(1)) + Day(1), LaxZonedDateTime())
@test isequal((non_existent + Hour(1)) + Day(1), LaxZonedDateTime())
end

@testset "compare" begin
Expand All @@ -64,7 +68,7 @@ end
a = LaxZonedDateTime(ZonedDateTime(2014,winnipeg))
b = ZonedDateTime(2015,winnipeg)
@test a < b

a = ZonedDateTime(2016, 11, 6, 1, 30, winnipeg, 1)
b = ZonedDateTime(2016, 11, 6, 1, winnipeg, 2)

Expand Down Expand Up @@ -187,5 +191,50 @@ end
@test_throws NonExistentTimeError ZonedDateTime(dne, :throw)
@test_throws NonExistentTimeError ZonedDateTime(dne)
end

end

end

@testset "convert to UTCDateTime" begin

@testset "basic" begin
lzdt = LaxZonedDateTime(DateTime(2020, 1, 1, 9, 30), winnipeg)
expected = UTCDateTime(ZonedDateTime(DateTime(2020, 1, 1, 9, 30), winnipeg))
@test UTCDateTime(lzdt) == expected
end

@testset "Ambiguous" begin
# Occurs during Fall DST - it's the same hour just in two different timezones
amb = LaxZonedDateTime(DateTime(2016, 11, 6, 1, 45), winnipeg)

utcdt = UTCDateTime(amb, :first)
exp_first = UTCDateTime(ZonedDateTime(2016, 11, 6, 1, 45, winnipeg, 1))
@test utcdt == exp_first

utcdt = UTCDateTime(amb, :last)
exp_last = UTCDateTime(ZonedDateTime(2016, 11, 6, 1, 45, winnipeg, 2))
@test utcdt == exp_last

@test_throws AmbiguousTimeError UTCDateTime(amb, :throw)
@test_throws AmbiguousTimeError UTCDateTime(amb)

end

@testset "NonExistent" begin
# Occurs during Spring DST
dne = LaxZonedDateTime(DateTime(2016, 3, 13, 2, 45), winnipeg)

# :first gets the time just before the transition occurred
utcdt = UTCDateTime(dne, :first)
exp_first = UTCDateTime(ZonedDateTime(2016, 3, 13, 1, 59, 59, 999, winnipeg))
@test utcdt == exp_first

# :last gets the hour after the transition occurred
utcdt = UTCDateTime(dne, :last)
exp_last = UTCDateTime(ZonedDateTime(2016, 3, 13, 3, 0, winnipeg))
@test utcdt == exp_last

@test_throws NonExistentTimeError UTCDateTime(dne, :throw)
@test_throws NonExistentTimeError UTCDateTime(dne)
end

end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ using LaxZonedDateTimes: isrepresentable, NonExistent
using Test
using TimeZones
using TimeZones: Transition, timezone
using UTCDateTimes

const winnipeg = TimeZone("America/Winnipeg")

Expand Down

4 comments on commit c8c5e28

@rofinn
Copy link
Member Author

@rofinn rofinn commented on c8c5e28 Feb 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error while trying to register: Changing package repo URL not allowed, please submit a pull request with the URL change to the target registry and retry.

@iamed2
Copy link
Member

@iamed2 iamed2 commented on c8c5e28 Feb 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/78457

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.4.0 -m "<description of version>" c8c5e28a881998985620743d4d8c4682bf3f2be1
git push origin v1.4.0

Please sign in to comment.