@@ -12,16 +12,17 @@ struct UnixTime <: Dates.AbstractDateTime
1212end
1313
1414function UnixTime (
15- y:: Integer ,
16- m:: Integer = 1 ,
17- d:: Integer = 1 ,
18- h:: Integer = 0 ,
19- mi:: Integer = 0 ,
20- s:: Integer = 0 ,
21- ms:: Integer = 0 ,
22- us:: Integer = 0 ,
23- ns:: Integer = 0 )
24- convert (UnixTime, DateTime (y, m, d, h, mi, s, ms)) + Nanosecond (us * 1000 + ns)
15+ y:: Integer ,
16+ m:: Integer = 1 ,
17+ d:: Integer = 1 ,
18+ h:: Integer = 0 ,
19+ mi:: Integer = 0 ,
20+ s:: Integer = 0 ,
21+ ms:: Integer = 0 ,
22+ us:: Integer = 0 ,
23+ ns:: Integer = 0
24+ )
25+ return convert (UnixTime, DateTime (y, m, d, h, mi, s, ms)) + Nanosecond (us * 1000 + ns)
2526end
2627
2728const UNIX_EPOCH = UnixTime (Dates. UTInstant (Nanosecond (0 )))
@@ -41,12 +42,12 @@ Base.:-(x::UnixTime, p::Period) = x + (-p)
4142
4243function Base.:+ (x:: UnixTime , p:: Union{Month, Year} )
4344 trunc_ns = mod (Dates. value (x), 1_000_000 )
44- convert (UnixTime, convert (DateTime, x) + p) + Nanosecond (trunc_ns)
45+ return convert (UnixTime, convert (DateTime, x) + p) + Nanosecond (trunc_ns)
4546end
4647
4748function Dates. DateTime (x:: UnixTime )
4849 instant_ms = Dates. UNIXEPOCH + div (x. instant. periods. value, 1_000_000 )
49- DateTime (Dates. UTM (instant_ms))
50+ return DateTime (Dates. UTM (instant_ms))
5051end
5152
5253Dates. Date (x:: UnixTime ) = Date (DateTime (x))
@@ -63,19 +64,39 @@ UnixTime(x::Date, y::Time) =
6364const DATEFORMAT = dateformat " yyyy-mm-ddTHH:MM:SS.sss"
6465
6566function UnixTime (s:: AbstractString )
66- try
67- @assert length (s) == 29
68- dt = DateTime (chop (s; tail= 6 ), DATEFORMAT)
69- ns = Nanosecond (parse (Int, last (s, 6 )))
70- UnixTime (dt) + ns
71- catch
72- throw (ArgumentError (" Invalid UnixTime string" ))
67+ # Find the decimal point if it exists
68+ dot_idx = findfirst (' .' , s)
69+
70+ # No fractional seconds, parse as DateTime
71+ isnothing (dot_idx) && return UnixTime (DateTime (s))
72+
73+ # Split into datetime and fractional parts
74+ dt_part = @view s[1 : (dot_idx - 1 )]
75+ frac_part = @view s[(dot_idx + 1 ): end ]
76+
77+ # Parse the datetime part
78+ dt = DateTime (dt_part)
79+
80+ # Parse fractional seconds (can be 1-9 digits)
81+ if isempty (frac_part) || ! all (isdigit, frac_part)
82+ throw (ArgumentError (" Invalid fractional seconds in UnixTime string" ))
7383 end
84+
85+ # Convert fractional seconds to nanoseconds
86+ # Pad or truncate to 9 digits (nanosecond precision)
87+ frac_digits = length (frac_part)
88+ ns_value = if frac_digits <= 9
89+ parse (Int, frac_part) * 10 ^ (9 - frac_digits)
90+ else
91+ parse (Int, frac_part[1 : 9 ])
92+ end
93+
94+ return UnixTime (dt) + Nanosecond (ns_value)
7495end
7596
7697function Base. convert (:: Type{UnixTime} , x:: DateTime )
7798 instant_ns = (Dates. value (x) - Dates. UNIXEPOCH) * 1_000_000
78- UnixTime (Dates. UTInstant (Nanosecond (instant_ns)))
99+ return UnixTime (Dates. UTInstant (Nanosecond (instant_ns)))
79100end
80101
81102# Promotion rules for comparing UnixTime with DateTime
@@ -90,11 +111,11 @@ function Base.show(io::IO, x::UnixTime)
90111 print (io, div (v, d) % 10 + ' 0' )
91112 d = div (d, 10 )
92113 end
93- nothing
114+ return nothing
94115end
95116
96117function Base. floor (x:: UnixTime , p:: Union{DatePeriod, TimePeriod} )
97- convert (UnixTime, floor (convert (DateTime, x), p))
118+ return convert (UnixTime, floor (convert (DateTime, x), p))
98119end
99120
100121Dates. guess (a:: UnixTime , b:: UnixTime , c) = (Dates. value (b) - Dates. value (a)) ÷ Dates. tons (c)
@@ -111,12 +132,12 @@ if Sys.islinux()
111132 ts = Ref {LinuxTimespec} ()
112133 ccall (:clock_gettime , Cint, (Cint, Ref{LinuxTimespec}), 0 , ts)
113134 x = ts[]
114- UnixTime (Dates. UTInstant (Nanosecond (x. seconds * 1_000_000_000 + x. nanoseconds)))
135+ return UnixTime (Dates. UTInstant (Nanosecond (x. seconds * 1_000_000_000 + x. nanoseconds)))
115136 end
116137else
117138 @inline function unix_now ()
118139 tv = Libc. TimeVal ()
119- UnixTime (Dates. UTInstant (Nanosecond (tv. sec * 1_000_000_000 + tv. usec * 1_000 )))
140+ return UnixTime (Dates. UTInstant (Nanosecond (tv. sec * 1_000_000_000 + tv. usec * 1_000 )))
120141 end
121142end
122143
0 commit comments