1
1
using Dates: AbstractDateTime, argerror, validargs
2
2
3
- const ZDT_TZS = Dict {UInt,Tuple{TimeZone,FixedTimeZone}} ()
3
+ # Stores non-bits data outside of the `ZonedDateTime` structure
4
+ const _ZDT_FIELDS = Vector {Tuple{TimeZone,FixedTimeZone}} ()
5
+
6
+ # Stored indexes into `_ZDT_FIELDS`
7
+ const _TZ_INDEX = Dict {Tuple{TimeZone,FixedTimeZone},Int} ()
8
+
4
9
5
10
# """
6
11
# ZonedDateTime
@@ -10,36 +15,62 @@ const ZDT_TZS = Dict{UInt,Tuple{TimeZone,FixedTimeZone}}()
10
15
11
16
struct ZonedDateTime <: AbstractDateTime
12
17
utc_datetime:: DateTime
13
- tz_hash :: UInt
18
+ _tz_index :: Int
14
19
15
20
function ZonedDateTime (utc_datetime:: DateTime , timezone:: TimeZone , zone:: FixedTimeZone )
16
- return new (utc_datetime, gen_tz_hash (timezone, zone))
21
+ return new (utc_datetime, _tz_index (timezone, zone))
17
22
end
18
23
19
24
function ZonedDateTime (utc_datetime:: DateTime , timezone:: VariableTimeZone , zone:: FixedTimeZone )
20
25
if timezone. cutoff != = nothing && utc_datetime >= timezone. cutoff
21
26
throw (UnhandledTimeError (timezone))
22
27
end
23
28
24
- return new (utc_datetime, gen_tz_hash (timezone, zone))
29
+ return new (utc_datetime, _tz_index (timezone, zone))
25
30
end
26
31
end
27
32
28
- function gen_tz_hash (tz:: TimeZone , zone:: FixedTimeZone )
29
- h = hash (tz)
30
- h = hash (zone, h)
33
+ function _tz_index (tz:: TimeZone , zone:: FixedTimeZone )
34
+ t = (tz, zone)
35
+
36
+ i = get! (_TZ_INDEX, t) do
37
+ push! (_ZDT_FIELDS, t)
38
+ lastindex (_ZDT_FIELDS)
39
+ end
40
+
41
+ return i
42
+ end
31
43
32
- if haskey (ZDT_TZS, h)
33
- stored_tz, stored_zone = ZDT_TZS[h]
34
- @assert tz == stored_tz
35
- @assert zone == stored_zone
44
+ function Base. getproperty (zdt:: ZonedDateTime , field:: Symbol )
45
+ if field === :zone
46
+ tz, zone = _ZDT_FIELDS[getfield (zdt, :_tz_index )]
47
+ return zone
48
+ elseif field === :timezone
49
+ tz, zone = _ZDT_FIELDS[getfield (zdt, :_tz_index )]
50
+ return tz
36
51
else
37
- ZDT_TZS[h] = (tz, zone )
52
+ return getfield (zdt, field )
38
53
end
54
+ end
39
55
40
- return h
56
+ # Overload serialization to ensure that `ZonedDateTime` serialization doesn't transfer
57
+ # state information which is specific to the current Julia process.
58
+ function Serialization. serialize (s:: AbstractSerializer , zdt:: ZonedDateTime )
59
+ Serialization. serialize_type (s, typeof (zdt))
60
+ serialize (s, zdt. utc_datetime)
61
+ serialize (s, zdt. timezone)
62
+ serialize (s, zdt. zone)
63
+ end
64
+
65
+ function Serialization. deserialize (s:: AbstractSerializer , :: Type{ZonedDateTime} )
66
+ utc_datetime = deserialize (s)
67
+ timezone = deserialize (s)
68
+ zone = deserialize (s)
69
+
70
+ return ZonedDateTime (utc_datetime, timezone, zone)
41
71
end
42
72
73
+
43
74
"""
44
75
ZonedDateTime(dt::DateTime, tz::TimeZone; from_utc=false) -> ZonedDateTime
45
76
@@ -165,15 +196,6 @@ function ZonedDateTime(date::Date, args...; kwargs...)
165
196
return ZonedDateTime (DateTime (date), args... ; kwargs... )
166
197
end
167
198
168
- function Base. getproperty (zdt:: ZonedDateTime , field:: Symbol )
169
- if field === :timezone || field === :zone
170
- tz, zone = ZDT_TZS[getfield (zdt, :tz_hash )]
171
- return field === :timezone ? tz : zone
172
- else
173
- return getfield (zdt, field)
174
- end
175
- end
176
-
177
199
# Promotion
178
200
179
201
# Because of the promoting fallback definitions for TimeType, we need a special case for
@@ -211,20 +233,3 @@ function Dates.validargs(::Type{ZonedDateTime}, y::Int64, m::Union{Int64, Int32}
211
233
istimezone (tz) || return argerror (" TimeZone: \" $tz \" is not a recognized time zone" )
212
234
return argerror ()
213
235
end
214
-
215
- # Overload serialization to ensure timezone information is transferred correctly
216
-
217
- function Serialization. serialize (s:: AbstractSerializer , zdt:: ZonedDateTime )
218
- Serialization. serialize_type (s, typeof (zdt))
219
- serialize (s, zdt. utc_datetime)
220
- serialize (s, zdt. timezone)
221
- serialize (s, zdt. zone)
222
- end
223
-
224
- function Serialization. deserialize (s:: AbstractSerializer , :: Type{ZonedDateTime} )
225
- utc_datetime = deserialize (s)
226
- timezone = deserialize (s)
227
- zone = deserialize (s)
228
-
229
- return ZonedDateTime (utc_datetime, timezone, zone)
230
- end
0 commit comments