Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameterize ZonedDateTime by TimeZone instance #318

Open
omus opened this issue Dec 21, 2020 · 5 comments
Open

Parameterize ZonedDateTime by TimeZone instance #318

omus opened this issue Dec 21, 2020 · 5 comments

Comments

@omus
Copy link
Member

omus commented Dec 21, 2020

Allows for enforcing that a Vector contains ZonedDateTimes all using the same TimeZone. This idea has been floated around before so I made this issue to centralize the conversation.

@omus
Copy link
Member Author

omus commented Dec 21, 2020

Requested in: apache/arrow-julia#50 (comment)

@oxinabox
Copy link
Contributor

oxinabox commented Apr 9, 2021

For it to be parametric on the value of the the timezone (ratehr than the type of the timezone) would require that the TimeZone type isbits.
Which is #271

@omus omus changed the title Parameterize ZonedDateTime by TimeZone Parameterize ZonedDateTime by TimeZone instance Apr 30, 2021
@omus
Copy link
Member Author

omus commented Apr 30, 2021

For it to be parametric on the value of the the timezone (ratehr than the type of the timezone) would require that the TimeZone type isbits.
Which is #271

So this issue is referring to having something like ZonedDateTime{tz"America/Winnipeg"}. Effectively this would mean having a separate type for each time zone making each time zone a singleton. The advantage here is you can use type constraints to enforce all elements of an array to be the same time zone and excise storing that information in the struct. The downside however additional overhead on Julia's type system with introducing 300+ types; complications with custom time zones and possibly serialization

@omus
Copy link
Member Author

omus commented May 18, 2021

An idea I'm experimenting with is using an intermediate type for the time zone. The advantage of such an approach is that it allows us to use a time zone as a type parameter without requiring the type storing the time zone information to have to be isbits which can be quite challenging.

Essentially this could work like:

using Dates: DateTime
using TimeZones: TimeZones, TimeZone, @tz_str

struct TZ{name} end
TZ{name}() where {name} = TimeZone(String(name))

macro TZ_str(name)
    :(TZ{$(Expr(:quote, Symbol(name)))})
end

struct ZonedDateTime{TZ}
    utc_instant::DateTime
    # zone::FixedTimeZone
end

function ZonedDateTime(dt::DateTime, tz::TimeZone)
    tz_type = TZ{Symbol(tz.name)}
    ZonedDateTime{tz_type}(dt)
end
TimeZones.timezone(::ZonedDateTime{TZ}) where TZ = TZ()
julia> ZonedDateTime{TZ"America/Winnipeg"}(DateTime(2021))
ZonedDateTime{TZ{Symbol("America/Winnipeg")}}(DateTime("2021-01-01T00:00:00"))

julia> ZonedDateTime(DateTime(2021), tz"America/Winnipeg")
ZonedDateTime{TZ{Symbol("America/Winnipeg")}}(DateTime("2021-01-01T00:00:00"))

There's even some room for optimization with this approach as TZ{name}() where {name} can be optimized with specialized methods such as TZ{Symbol("...")} = tz"...":

using TimeZones

struct TZ1{name} end
struct TZ2{name} end

macro TZ1_str(name)
    :(TZ1{$(Expr(:quote, Symbol(name)))})
end
macro TZ2_str(name)
    :(TZ2{$(Expr(:quote, Symbol(name)))})
end

TZ1{name}() where {name} = TimeZone(String(name))
TZ2"America/Winnipeg"() = tz"America/Winnipeg"
julia> @btime TZ1"America/Winnipeg"()
  84.699 ns (3 allocations: 112 bytes)
America/Winnipeg (UTC-6/UTC-5)

julia> @btime TZ2"America/Winnipeg"()
  1.563 ns (0 allocations: 0 bytes)
America/Winnipeg (UTC-6/UTC-5)

One thing I'm not loving about this approach is how the type is displayed but overall that's pretty minor. I need to do some additional experimentation yet.

@omus
Copy link
Member Author

omus commented Aug 18, 2021

Trying to get some activity on custom type printing: JuliaLang/julia#24195 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants