• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37539

pending completion
#37539

push

local

web-flow
add devdocs how to profile package precompilation with tracy (#49784)

1 of 1 new or added line in 1 file covered. (100.0%)

72624 of 83590 relevant lines covered (86.88%)

35576540.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.68
/stdlib/Dates/src/types.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
abstract type AbstractTime end
4

5
"""
6
    Period
7
    Year
8
    Quarter
9
    Month
10
    Week
11
    Day
12
    Hour
13
    Minute
14
    Second
15
    Millisecond
16
    Microsecond
17
    Nanosecond
18

19
`Period` types represent discrete, human representations of time.
20
"""
21
abstract type Period     <: AbstractTime end
22

23
"""
24
    DatePeriod
25
    Year
26
    Quarter
27
    Month
28
    Week
29
    Day
30

31
Intervals of time greater than or equal to a day.
32
Conventional comparisons between `DatePeriod`s are not all valid.
33
(eg `Week(1) == Day(7)`, but `Year(1) != Day(365)`)
34
"""
35
abstract type DatePeriod <: Period end
36

37
"""
38
    TimePeriod
39
    Hour
40
    Minute
41
    Second
42
    Millisecond
43
    Microsecond
44
    Nanosecond
45

46
Intervals of time less than a day.
47
Conversions between all `TimePeriod`s are permissible.
48
(eg `Hour(1) == Minute(60) == Second(3600)`)
49
"""
50
abstract type TimePeriod <: Period end
51

52
for T in (:Year, :Quarter, :Month, :Week, :Day)
53
    @eval struct $T <: DatePeriod
54
        value::Int64
55
        $T(v::Number) = new(v)
6,309,631✔
56
    end
57
end
58
for T in (:Hour, :Minute, :Second, :Millisecond, :Microsecond, :Nanosecond)
59
    @eval struct $T <: TimePeriod
60
        value::Int64
61
        $T(v::Number) = new(v)
585,671✔
62
    end
63
end
64

65
"""
66
    Year(v)
67
    Quarter(v)
68
    Month(v)
69
    Week(v)
70
    Day(v)
71
    Hour(v)
72
    Minute(v)
73
    Second(v)
74
    Millisecond(v)
75
    Microsecond(v)
76
    Nanosecond(v)
77

78
Construct a `Period` type with the given `v` value. Input must be losslessly convertible
79
to an [`Int64`](@ref).
80
"""
81
Period(v)
82

83
"""
84
    Instant
85

86
`Instant` types represent integer-based, machine representations of time as continuous
87
timelines starting from an epoch.
88
"""
89
abstract type Instant <: AbstractTime end
90

91
"""
92
    UTInstant{T}
93

94
The `UTInstant` represents a machine timeline based on UT time (1 day = one revolution of
95
the earth). The `T` is a `Period` parameter that indicates the resolution or precision of
96
the instant.
97
"""
98
struct UTInstant{P<:Period} <: Instant
99
    periods::P
2,535,906✔
100
end
101

102
# Convenience default constructors
103
UTM(x) = UTInstant(Millisecond(x))
526,485,036✔
104
UTD(x) = UTInstant(Day(x))
2,257,695✔
105

106
# Calendar types provide rules for interpreting instant
107
# timelines in human-readable form.
108
abstract type Calendar <: AbstractTime end
109

110
# ISOCalendar implements the ISO 8601 standard (en.wikipedia.org/wiki/ISO_8601)
111
# Notably based on the proleptic Gregorian calendar
112
# ISOCalendar provides interpretation rules for UTInstants to civil date and time parts
113
struct ISOCalendar <: Calendar end
114

115
"""
116
    TimeZone
117

118
Geographic zone generally based on longitude determining what the time is at a certain location.
119
Some time zones observe daylight savings (eg EST -> EDT).
120
For implementations and more support, see the [`TimeZones.jl`](https://github.com/JuliaTime/TimeZones.jl) package
121
"""
122
abstract type TimeZone end
123

124
"""
125
    UTC
126

127
`UTC`, or Coordinated Universal Time, is the [`TimeZone`](@ref) from which all others are measured.
128
It is associated with the time at 0° longitude. It is not adjusted for daylight savings.
129
"""
130
struct UTC <: TimeZone end
131

132
"""
133
    TimeType
134

135
`TimeType` types wrap `Instant` machine instances to provide human representations of the
136
machine instant. `Time`, `DateTime` and `Date` are subtypes of `TimeType`.
137
"""
138
abstract type TimeType <: AbstractTime end
139

140
abstract type AbstractDateTime <: TimeType end
141

142
"""
143
    DateTime
144

145
`DateTime` wraps a `UTInstant{Millisecond}` and interprets it according to the proleptic
146
Gregorian calendar.
147
"""
148
struct DateTime <: AbstractDateTime
149
    instant::UTInstant{Millisecond}
150
    DateTime(instant::UTInstant{Millisecond}) = new(instant)
526,485,037✔
151
end
152

153
"""
154
    Date
155

156
`Date` wraps a `UTInstant{Day}` and interprets it according to the proleptic Gregorian calendar.
157
"""
158
struct Date <: TimeType
159
    instant::UTInstant{Day}
160
    Date(instant::UTInstant{Day}) = new(instant)
2,257,696✔
161
end
162

163
"""
164
    Time
165

166
`Time` wraps a `Nanosecond` and represents a specific moment in a 24-hour day.
167
"""
168
struct Time <: TimeType
169
    instant::Nanosecond
170
    Time(instant::Nanosecond) = new(mod(instant, 86400000000000))
37,198✔
171
end
172

173
# Convert y,m,d to # of Rata Die days
174
# Works by shifting the beginning of the year to March 1,
175
# so a leap day is the very last day of the year
176
const SHIFTEDMONTHDAYS = (306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275)
177
function totaldays(y, m, d)
2,091,966✔
178
    # If we're in Jan/Feb, shift the given year back one
179
    z = m < 3 ? y - 1 : y
2,091,966✔
180
    mdays = SHIFTEDMONTHDAYS[m]
2,091,966✔
181
    # days + month_days + year_days
182
    return d + mdays + 365z + fld(z, 4) - fld(z, 100) + fld(z, 400) - 306
2,091,966✔
183
end
184

185
# If the year is divisible by 4, except for every 100 years, except for every 400 years
186
isleapyear(y) = (y % 4 == 0) && ((y % 100 != 0) || (y % 400 == 0))
158,561✔
187

188
# Number of days in month
189
const DAYSINMONTH = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
190
daysinmonth(y,m) = DAYSINMONTH[m] + (m == 2 && isleapyear(y))
4,182,970✔
191

192
### UTILITIES ###
193

194
# These are necessary because the type constructors for TimeType subtypes can
195
# throw, and we want to be able to use tryparse without requiring a try/catch.
196
# This is made easier by providing a helper function that checks arguments, so
197
# we can validate arguments in tryparse.
198

199
"""
200
    validargs(::Type{<:TimeType}, args...) -> Union{ArgumentError, Nothing}
201

202
Determine whether the given arguments constitute valid inputs for the given type.
203
Returns either an `ArgumentError`, or [`nothing`](@ref) in case of success.
204
"""
205
function validargs end
206

207
# Julia uses 24-hour clocks internally, but user input can be AM/PM with 12pm == noon and 12am == midnight.
208
@enum AMPM AM PM TWENTYFOURHOUR
209
function adjusthour(h::Int64, ampm::AMPM)
259✔
210
    ampm == TWENTYFOURHOUR && return h
291,812✔
211
    ampm == PM && h < 12 && return h + 12
24✔
212
    ampm == AM && h == 12 && return Int64(0)
20✔
213
    return h
12✔
214
end
215

216
### CONSTRUCTORS ###
217
# Core constructors
218
"""
219
    DateTime(y, [m, d, h, mi, s, ms]) -> DateTime
220

221
Construct a `DateTime` type by parts. Arguments must be convertible to [`Int64`](@ref).
222
"""
223
function DateTime(y::Int64, m::Int64=1, d::Int64=1,
371,843✔
224
                  h::Int64=0, mi::Int64=0, s::Int64=0, ms::Int64=0, ampm::AMPM=TWENTYFOURHOUR)
225
    err = validargs(DateTime, y, m, d, h, mi, s, ms, ampm)
663,368✔
226
    err === nothing || throw(err)
331,986✔
227
    h = adjusthour(h, ampm)
331,917✔
228
    rata = ms + 1000 * (s + 60mi + 3600h + 86400 * totaldays(y, m, d))
331,950✔
229
    return DateTime(UTM(rata))
331,950✔
230
end
231

232
function validargs(::Type{DateTime}, y::Int64, m::Int64, d::Int64,
331,969✔
233
                   h::Int64, mi::Int64, s::Int64, ms::Int64, ampm::AMPM=TWENTYFOURHOUR)
234
    0 < m < 13 || return ArgumentError("Month: $m out of range (1:12)")
331,972✔
235
    0 < d < daysinmonth(y, m) + 1 || return ArgumentError("Day: $d out of range (1:$(daysinmonth(y, m)))")
331,969✔
236
    if ampm == TWENTYFOURHOUR # 24-hour clock
331,963✔
237
        -1 < h < 24 || (h == 24 && mi==s==ms==0) ||
331,959✔
238
            return ArgumentError("Hour: $h out of range (0:23)")
239
    else
240
        0 < h < 13 || return ArgumentError("Hour: $h out of range (1:12)")
12✔
241
    end
242
    -1 < mi < 60 || return ArgumentError("Minute: $mi out of range (0:59)")
331,959✔
243
    -1 < s < 60 || return ArgumentError("Second: $s out of range (0:59)")
331,957✔
244
    -1 < ms < 1000 || return ArgumentError("Millisecond: $ms out of range (0:999)")
331,955✔
245
    return nothing
331,951✔
246
end
247

248
DateTime(dt::Base.Libc.TmStruct) = DateTime(1900 + dt.year, 1 + dt.month, dt.mday, dt.hour, dt.min, dt.sec)
1✔
249

250
"""
251
    Date(y, [m, d]) -> Date
252

253
Construct a `Date` type by parts. Arguments must be convertible to [`Int64`](@ref).
254
"""
255
function Date(y::Int64, m::Int64=1, d::Int64=1)
1,900,299✔
256
    err = validargs(Date, y, m, d)
1,900,304✔
257
    err === nothing || throw(err)
1,900,131✔
258
    return Date(UTD(totaldays(y, m, d)))
1,900,115✔
259
end
260

261
function validargs(::Type{Date}, y::Int64, m::Int64, d::Int64)
100,131✔
262
    0 < m < 13 || return ArgumentError("Month: $m out of range (1:12)")
1,900,128✔
263
    0 < d < daysinmonth(y, m) + 1 || return ArgumentError("Day: $d out of range (1:$(daysinmonth(y, m)))")
1,900,125✔
264
    return nothing
1,900,115✔
265
end
266

267
Date(dt::Base.Libc.TmStruct) = Date(1900 + dt.year, 1 + dt.month, dt.mday)
1✔
268

269
"""
270
    Time(h, [mi, s, ms, us, ns]) -> Time
271

272
Construct a `Time` type by parts. Arguments must be convertible to [`Int64`](@ref).
273
"""
274
function Time(h::Int64, mi::Int64=0, s::Int64=0, ms::Int64=0, us::Int64=0, ns::Int64=0, ampm::AMPM=TWENTYFOURHOUR)
282✔
275
    err = validargs(Time, h, mi, s, ms, us, ns, ampm)
282✔
276
    err === nothing || throw(err)
181✔
277
    h = adjusthour(h, ampm)
157✔
278
    return Time(Nanosecond(ns + 1000us + 1000000ms + 1000000000s + 60000000000mi + 3600000000000h))
145✔
279
end
280

281
function validargs(::Type{Time}, h::Int64, mi::Int64, s::Int64, ms::Int64, us::Int64, ns::Int64, ampm::AMPM=TWENTYFOURHOUR)
163✔
282
    if ampm == TWENTYFOURHOUR # 24-hour clock
163✔
283
        -1 < h < 24 || return ArgumentError("Hour: $h out of range (0:23)")
151✔
284
    else
285
        0 < h < 13 || return ArgumentError("Hour: $h out of range (1:12)")
15✔
286
    end
287
    -1 < mi < 60 || return ArgumentError("Minute: $mi out of range (0:59)")
160✔
288
    -1 < s < 60 || return ArgumentError("Second: $s out of range (0:59)")
157✔
289
    -1 < ms < 1000 || return ArgumentError("Millisecond: $ms out of range (0:999)")
153✔
290
    -1 < us < 1000 || return ArgumentError("Microsecond: $us out of range (0:999)")
151✔
291
    -1 < ns < 1000 || return ArgumentError("Nanosecond: $ns out of range (0:999)")
149✔
292
    return nothing
145✔
293
end
294

295
Time(dt::Base.Libc.TmStruct) = Time(dt.hour, dt.min, dt.sec)
7✔
296

297
# Convenience constructors from Periods
298
function DateTime(y::Year, m::Month=Month(1), d::Day=Day(1),
31✔
299
                  h::Hour=Hour(0), mi::Minute=Minute(0),
300
                  s::Second=Second(0), ms::Millisecond=Millisecond(0))
301
    return DateTime(value(y), value(m), value(d),
31✔
302
                    value(h), value(mi), value(s), value(ms))
303
end
304

305
Date(y::Year, m::Month=Month(1), d::Day=Day(1)) = Date(value(y), value(m), value(d))
11✔
306

307
function Time(h::Hour, mi::Minute=Minute(0), s::Second=Second(0),
39✔
308
              ms::Millisecond=Millisecond(0),
309
              us::Microsecond=Microsecond(0), ns::Nanosecond=Nanosecond(0))
310
    return Time(value(h), value(mi), value(s), value(ms), value(us), value(ns))
39✔
311
end
312

313
# To allow any order/combination of Periods
314

315
"""
316
    DateTime(periods::Period...) -> DateTime
317

318
Construct a `DateTime` type by `Period` type parts. Arguments may be in any order. DateTime
319
parts not provided will default to the value of `Dates.default(period)`.
320
"""
321
function DateTime(period::Period, periods::Period...)
3✔
322
    y = Year(1); m = Month(1); d = Day(1)
9✔
323
    h = Hour(0); mi = Minute(0); s = Second(0); ms = Millisecond(0)
12✔
324
    for p in (period, periods...)
3✔
325
        isa(p, Year) && (y = p::Year)
12✔
326
        isa(p, Month) && (m = p::Month)
12✔
327
        isa(p, Day) && (d = p::Day)
12✔
328
        isa(p, Hour) && (h = p::Hour)
12✔
329
        isa(p, Minute) && (mi = p::Minute)
12✔
330
        isa(p, Second) && (s = p::Second)
12✔
331
        isa(p, Millisecond) && (ms = p::Millisecond)
12✔
332
    end
15✔
333
    return DateTime(y, m, d, h, mi, s, ms)
3✔
334
end
335

336
"""
337
    Date(period::Period...) -> Date
338

339
Construct a `Date` type by `Period` type parts. Arguments may be in any order. `Date` parts
340
not provided will default to the value of `Dates.default(period)`.
341
"""
342
function Date(period::Period, periods::Period...)
5✔
343
    y = Year(1); m = Month(1); d = Day(1)
15✔
344
    for p in (period, periods...)
5✔
345
        isa(p, Year) && (y = p::Year)
10✔
346
        isa(p, Month) && (m = p::Month)
10✔
347
        isa(p, Day) && (d = p::Day)
10✔
348
    end
14✔
349
    return Date(y, m, d)
5✔
350
end
351

352
"""
353
    Time(period::TimePeriod...) -> Time
354

355
Construct a `Time` type by `Period` type parts. Arguments may be in any order. `Time` parts
356
not provided will default to the value of `Dates.default(period)`.
357
"""
358
function Time(period::TimePeriod, periods::TimePeriod...)
3✔
359
    h = Hour(0); mi = Minute(0); s = Second(0)
9✔
360
    ms = Millisecond(0); us = Microsecond(0); ns = Nanosecond(0)
9✔
361
    for p in (period, periods...)
3✔
362
        isa(p, Hour) && (h = p::Hour)
15✔
363
        isa(p, Minute) && (mi = p::Minute)
15✔
364
        isa(p, Second) && (s = p::Second)
15✔
365
        isa(p, Millisecond) && (ms = p::Millisecond)
15✔
366
        isa(p, Microsecond) && (us = p::Microsecond)
15✔
367
        isa(p, Nanosecond) && (ns = p::Nanosecond)
15✔
368
    end
18✔
369
    return Time(h, mi, s, ms, us, ns)
3✔
370
end
371

372
# Convenience constructor for DateTime from Date and Time
373
"""
374
    DateTime(d::Date, t::Time)
375

376
Construct a `DateTime` type by `Date` and `Time`.
377
Non-zero microseconds or nanoseconds in the `Time` type will result in an
378
`InexactError`.
379

380
!!! compat "Julia 1.1"
381
    This function requires at least Julia 1.1.
382

383
```jldoctest
384
julia> d = Date(2018, 1, 1)
385
2018-01-01
386

387
julia> t = Time(8, 15, 42)
388
08:15:42
389

390
julia> DateTime(d, t)
391
2018-01-01T08:15:42
392
```
393
"""
394
function DateTime(dt::Date, t::Time)
×
395
    (microsecond(t) > 0 || nanosecond(t) > 0) && throw(InexactError(:DateTime, DateTime, t))
×
396
    y, m, d = yearmonthday(dt)
×
397
    return DateTime(y, m, d, hour(t), minute(t), second(t), millisecond(t))
×
398
end
399

400
# Fallback constructors
401
DateTime(y, m=1, d=1, h=0, mi=0, s=0, ms=0, ampm::AMPM=TWENTYFOURHOUR) = DateTime(Int64(y), Int64(m), Int64(d), Int64(h), Int64(mi), Int64(s), Int64(ms), ampm)
972✔
402
Date(y, m=1, d=1) = Date(Int64(y), Int64(m), Int64(d))
30✔
403
Time(h, mi=0, s=0, ms=0, us=0, ns=0, ampm::AMPM=TWENTYFOURHOUR) = Time(Int64(h), Int64(mi), Int64(s), Int64(ms), Int64(us), Int64(ns), ampm)
14✔
404

405
# Traits, Equality
406
Base.isfinite(::Union{Type{T}, T}) where {T<:TimeType} = true
3✔
407
calendar(dt::DateTime) = ISOCalendar
1✔
408
calendar(dt::Date) = ISOCalendar
1✔
409

410
"""
411
    eps(::Type{DateTime}) -> Millisecond
412
    eps(::Type{Date}) -> Day
413
    eps(::Type{Time}) -> Nanosecond
414
    eps(::TimeType) -> Period
415

416
Return the smallest unit value supported by the `TimeType`.
417

418
# Examples
419
```jldoctest
420
julia> eps(DateTime)
421
1 millisecond
422

423
julia> eps(Date)
424
1 day
425

426
julia> eps(Time)
427
1 nanosecond
428
```
429
"""
430
Base.eps(::Union{Type{DateTime}, Type{Date}, Type{Time}, TimeType})
431

432
Base.eps(::Type{DateTime}) = Millisecond(1)
2✔
433
Base.eps(::Type{Date}) = Day(1)
2✔
434
Base.eps(::Type{Time}) = Nanosecond(1)
2✔
435
Base.eps(::T) where T <: TimeType = eps(T)::Period
3✔
436

437
# zero returns dt::T - dt::T
438
Base.zero(::Type{DateTime}) = Millisecond(0)
8✔
439
Base.zero(::Type{Date}) = Day(0)
8✔
440
Base.zero(::Type{Time}) = Nanosecond(0)
8✔
441
Base.zero(::T) where T <: TimeType = zero(T)::Period
3✔
442

443

444
Base.typemax(::Union{DateTime, Type{DateTime}}) = DateTime(146138512, 12, 31, 23, 59, 59)
27✔
445
Base.typemin(::Union{DateTime, Type{DateTime}}) = DateTime(-146138511, 1, 1, 0, 0, 0)
25✔
446
Base.typemax(::Union{Date, Type{Date}}) = Date(252522163911149, 12, 31)
20✔
447
Base.typemin(::Union{Date, Type{Date}}) = Date(-252522163911150, 1, 1)
19✔
448
Base.typemax(::Union{Time, Type{Time}}) = Time(23, 59, 59, 999, 999, 999)
14✔
449
Base.typemin(::Union{Time, Type{Time}}) = Time(0)
14✔
450
# Date-DateTime promotion, isless, ==
451
Base.promote_rule(::Type{Date}, x::Type{DateTime}) = DateTime
14✔
452
Base.isless(x::T, y::T) where {T<:TimeType} = isless(value(x), value(y))
1,056,304,871✔
453
Base.isless(x::TimeType, y::TimeType) = isless(promote(x, y)...)
5✔
454
(==)(x::T, y::T) where {T<:TimeType} = (==)(value(x), value(y))
1,055,259,804✔
455
(==)(x::TimeType, y::TimeType) = (===)(promote(x, y)...)
10✔
456
Base.min(x::AbstractTime) = x
5✔
457
Base.max(x::AbstractTime) = x
5✔
458
Base.minmax(x::AbstractTime) = (x, x)
5✔
459
Base.hash(x::Time, h::UInt) =
250✔
460
    hash(hour(x), hash(minute(x), hash(second(x),
461
        hash(millisecond(x), hash(microsecond(x), hash(nanosecond(x), h))))))
462

463
Base.sleep(duration::Period) = sleep(toms(duration) / 1000)
4✔
464

465
function Base.Timer(delay::Period; interval::Period=Second(0))
8✔
466
    Timer(toms(delay) / 1000, interval=toms(interval) / 1000)
4✔
467
end
468

469
function Base.timedwait(testcb, timeout::Period; pollint::Period=Millisecond(100))
2✔
470
    timedwait(testcb, toms(timeout) / 1000, pollint=toms(pollint) / 1000)
1✔
471
end
472

473
Base.OrderStyle(::Type{<:AbstractTime}) = Base.Ordered()
×
474
Base.ArithmeticStyle(::Type{<:AbstractTime}) = Base.ArithmeticWraps()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc