Skip to content

Commit

Permalink
Integrate with Dates I/O
Browse files Browse the repository at this point in the history
  • Loading branch information
helgee committed Aug 12, 2018
1 parent a4c49f4 commit 95ca16f
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/AstroDates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ using ..TimeScales: TimeScale

import Base: time, show
import Dates
import Dates: year, month, day, hour, minute, second

export Date, Time, DateTime,
year, month, day, j2000day, calendar,
Expand Down Expand Up @@ -146,6 +147,10 @@ function Date(epoch, offset)
end

function Date(year, month, day)
if month < 1 || month > 12
throw(ArgumentError("Invalid month number: $month"))
end

check = Date(j2000day(year, month, day))
if check.year != year || check.month != month || check.day != day
throw(ArgumentError("Invalid date."))
Expand Down
20 changes: 20 additions & 0 deletions src/AstroTime.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@ include("Epochs.jl")
@reexport using .Epochs

function __init__()
Dates.CONVERSION_SPECIFIERS['t'] = TimeScale
Dates.CONVERSION_DEFAULTS[TimeScale] = ""
Dates.CONVERSION_TRANSLATIONS[Epoch] = (
Dates.Year,
Dates.Month,
Dates.Day,
Dates.Hour,
Dates.Minute,
Dates.Second,
Dates.Millisecond,
TimeScale,
)
@eval begin
global ISOEpochFormat = Dates.DateFormat("yyyy-mm-ddTHH:MM:SS.sss ttt")
Dates.default_format(::Type{Epoch}) = ISOEpochFormat
end

for scale in TimeScales.ACRONYMS
epoch = Symbol(scale, "Epoch")
@eval begin
Expand Down Expand Up @@ -54,11 +71,13 @@ true
macro timescale(scale::Symbol, ep::Symbol, args...)
epoch = Expr(:escape, Symbol(scale, "Epoch"))
sc = Expr(:escape, scale)
name = String(scale)
ep_arg = Expr(:escape, ep)
return quote
struct $sc <: TimeScale end
const $epoch = Epoch{$sc()}
Base.show(io::IO, $sc) = print(io, string(typeof($sc)))
AstroTime.TimeScales.tryparse(::Val{Symbol($name)}) = $sc()

Dates.CONVERSION_TRANSLATIONS[$epoch] = (
Dates.Year,
Expand All @@ -73,6 +92,7 @@ macro timescale(scale::Symbol, ep::Symbol, args...)
function AstroTime.Epochs.tai_offset(::$sc, $ep)
$args[end]
end

nothing
end
end
Expand Down
23 changes: 23 additions & 0 deletions src/Epochs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ using EarthOrientation: getΔUT1

import Base: -, +, <, ==, isapprox, isless, show
import Dates
import Dates: format, parse

using ..TimeScales
using ..AstroDates
Expand Down Expand Up @@ -74,6 +75,15 @@ function Epoch{S}(date::Date, time::Time) where S
Epoch{S}(epoch, offset)
end

Epoch(str::AbstractString, df::Dates.DateFormat=ISOEpochFormat) = parse(Epoch, str, df)

Epoch(str::AbstractString, format::AbstractString) = Epoch(str, Dates.DateFormat(format))

Epoch{S}(str::AbstractString,
df::Dates.DateFormat=Dates.default_format(Epoch{S})) where {S} = parse(Epoch{S}, str, df)

Epoch{S}(str::AbstractString, format::AbstractString) where {S} = Epoch{S}(str, Dates.DateFormat(format))

Epoch{S}(d::Date) where {S} = Epoch{S}(d, AstroDates.H00)

Epoch{S}(dt::DateTime) where {S} = Epoch{S}(date(dt), time(dt))
Expand All @@ -88,6 +98,12 @@ function Epoch{S}(year::Int, month::Int, day::Int, hour::Int,
Epoch{S}(Date(year, month, day), Time(hour, minute, second + 1e-3milliseconds))
end

function Epoch(year::Int, month::Int, day::Int, hour::Int,
minute::Int, second::Int, milliseconds::Int,
scale::S) where S<:TimeScale
Epoch{scale}(Date(year, month, day), Time(hour, minute, second + 1e-3milliseconds))
end

function Epoch{S2}(ep::Epoch{S1}) where {S1, S2}
Δt = tai_offset(S2, ep) - tai_offset(S1, ep)
Epoch{S2}(ep.epoch, ep.offset, Δt)
Expand Down Expand Up @@ -124,4 +140,11 @@ const FUTURE_INFINITY = TAIEpoch(UNIX_EPOCH, Inf)

const EPOCH_77 = Epoch{TAI}(1977, 1, 1)

function Dates.validargs(::Type{Epoch}, y::Int64, m::Int64, d::Int64,
h::Int64, mi::Int64, s::Int64, ms::Int64, ts::S) where S<:TimeScale
err = Dates.validargs(Dates.DateTime, y, m, d, h, mi, s, ms)
err !== nothing || return err
return Dates.argerror()
end

end
15 changes: 15 additions & 0 deletions src/TimeScales.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module TimeScales

import Dates

export TimeScale

"""
Expand Down Expand Up @@ -44,7 +46,20 @@ for (acronym, scale) in zip(ACRONYMS, SCALES)
export $scale, $acronym

Base.show(io::IO, ::$scale) = print(io, $name)
tryparse(::Val{Symbol($name)}) = $acronym
end
end

tryparse(s::T) where T<:AbstractString = tryparse(Val(Symbol(s)))
tryparse(::T) where T = nothing

@inline function Dates.tryparsenext(d::Dates.DatePart{'t'}, str, i, len, locale)
next = Dates.tryparsenext_word(str, i, len, locale, Dates.max_width(d))
next === nothing && return nothing
word, i = next
val = tryparse(word)
val === nothing && return nothing
return val, i
end

end

0 comments on commit 95ca16f

Please sign in to comment.