-
Notifications
You must be signed in to change notification settings - Fork 10
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
Demote UTC to I/O format and general overhaul #58
Conversation
Workaround for JuliaLang/julia#37579
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked more the implementation than the merit of the changes 🙂
|
||
function findyear(calendar, j2000day::Int32) | ||
function findyear(calendar, j2000day) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I correct to think we assume j2000day
to be Union{Int32,Int64}
? Or is it Int
? If this is limited to Int32
/Int64
it can also be Int64(j2000day)
without any if*
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about this. It seems that Int64(j2000day)
allocates and I saw lots jl_box_int64
in my profiles. This is ugly but performance is an order of magnitude better: j2kday = ifelse(j2000day isa Int32, widen(j2000day), j2000day)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And it is Int
so changes only with Sys.WORD_SIZE
.
|
||
function findyear(calendar, j2000day::Int32) | ||
function findyear(calendar, j2000day) | ||
j2kday = ifelse(j2000day isa Int32, widen(j2000day), j2000day) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Int64(<literal>)
allocates apparently so this has a significant performance impact.
@@ -216,113 +175,235 @@ const UNIX_EPOCH = Date(1970, 1, 1) | |||
struct Time{T} | |||
hour::Int | |||
minute::Int | |||
second::T | |||
second::Int | |||
fraction::T |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the representation of Time
to have the same accuracy characteristics as Epoch
. As a result, converting Epoch
to AstroTime.DateTime
and vice versa is losless. Dates.DateTime
on the other hand is still limited to millisecond precision.
|
||
const H00 = Time(0, 0, 0.0) | ||
const H12 = Time(12, 0, 0.0) | ||
function subsecond(fraction, n, r) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This stumped me for a while. See also the method below. As a result, we now get sensible values for milli-/micro-/nanoseconds as if they were integral values and hiding the inherent floating point inaccuracies.
julia> subsecond(0.1839999999999975, 9)
0
julia> subsecond(0.1839999999999975, 3)
184
julia> subsecond(0.123456789, 9)
789
julia> subsecond(0.123456789, 3)
123
print(io, timescale(ep)) | ||
abstract type FractionOfSecondToken end | ||
|
||
@inline function Dates.tryparsenext(d::Dates.DatePart{'f'}, str, i, len, locale) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can now parse timestamps with full Float64
precision by using the f
field, e.g. dateformat"yyyy-mm-ddTHH:MM:SS.ffffffff
. Thereby circumventing JuliaLang/julia#37579
``` | ||
""" | ||
@inline function getoffset(::CoordinatedUniversalTime, ::UniversalTime, | ||
@inline function getoffset(::InternationalAtomicTime, ::UniversalTime, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UT1 is linked to TAI now.
const LEAP_TAI = LEAP_J2000 .+ round.(Int, LeapSeconds.LEAP_SECONDS) .- 1 | ||
const LEAP_TAI_SET = Set(LEAP_TAI) | ||
|
||
function from_utc(str::AbstractString; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the headline change. There is no Epoch{UTC}
anymore but we can still convert to/from UTC via the dedicated from_utc
and to_utc
. The discussion about this is in #50 (comment).
TL;DR: The Epoch
data format is incompatible with a discontinuous timescale like UTC (and only UTC 👎 ). Thus, it makes no sense to rewrite the whole library and add a lot of edge cases for UTC. The best way of dealing with UTC and leap seconds is by keeping them on the outer edge of your code or pretend they do not exist like Google (https://github.com/google/unsmear). Friends do not let friends use UTC for mission-critical time keeping.
|
||
to_utc(ep, args...) = to_utc(String, ep, args...) | ||
|
||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now
returns actual TAI (from UTC) instead of local time. No idea what will happen during a leap second though 😬
@test step(rng) == 13seconds | ||
@test last(rng) == UTCEpoch(2018, 1, 1, 0, 0, 52.0) | ||
end | ||
@testset "Leap Seconds" begin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these become obsolete by removing UTC 😅
@timescale GMT UTC | ||
AstroTime.Epochs.getoffset(::GMTScale, ::CoordinatedUniversalTime, _, _) = 0.0 | ||
AstroTime.Epochs.getoffset(::CoordinatedUniversalTime, ::GMTScale, _, _) = 0.0 | ||
# TODO: Change me |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These examples are not great anymore and I will try to come up with new ones during the doc update.
Boy, that escalated quickly!
I realize that this is a lot to review so I will leave comments inline to highlight the most important changes. Documentation updates will follow in a separate PR.
Fixes #50
Fixes #53