Rounding DateTime string

As discussed here

https://discourse.julialang.org/t/parsing-datetime-string/

it’s quite a hassle to convert a datetime string to a DateTime object when the string contains more digits than DateTime can accommodate.

Is there already a simple solution?

If not . . .

There is an analogous situation when you want an approximate Int value from a string that represents a floating point number:

f = parse(Float64, "3.14")
i = round(Int, f)

So, if there were a “floating-point DateTime” type, we would solve the problem by

f = parse(FloatDateTime, "2023-07-01T12:34:56.123456789")
i = round(DateTime, f)

where the millisecond part of FloatDateTime would be represented internally by a Float64 . . . Likely this would be overkill as you would then have to implement all operations on FloatDateTime . . .

Barring such a drastic solution, I would just split the string at the decimal point, convert the left part to a DateTime, approximate the right part to a 3-digit precision, perhaps with a warning message when the milliseconds is an approximation, and add the latter milliseconds to the former DateTime; or perhaps I would snatch the parser code from the Dates package and modify the milliseconds part to do the approximation; and always use such a personal parser every time I parse a DateTime . . .

While not ideal, at least it “solves” the problem:

julia> str = "2023-07-01T12:34:56.123456789"
"2023-07-01T12:34:56.123456789"

julia> str2 = only(match(r"(.*\.\d{3})", str)) # discard anything above 
"2023-07-01T12:34:56.123"

julia> DateTime(str2)
2023-07-01T12:34:56.123

This is better in the sense that it takes care of any rounding errors we ignored with the previous solution:

julia> dt, p = match(r"(.*)\.(\d*)", str) # split it to datetime and the fraction of the seconds
RegexMatch("2023-07-01T12:34:56.123456789", 1="2023-07-01T12:34:56", 2="123456789")

julia> ms = 1000parse(Float64, "0."*p)
123.456789

julia> DateTime(dt) + Millisecond(round(Int, ms)) # DateTime's accuracy goes only to milliseconds
2023-07-01T12:34:56.123
4 Likes

Thanks! That’s indeed nice. I guess I’ll put that (plus error handling) into my personal “kitchen sink” module and use it everywhere I need to parse DateTime strings.

Here is a bit of simplification:

(dt, p) = split(str, ".")

According to the ISO standard (see the reference at the bottom of this posting), the decimal point is the only possibility that a DateTime string includes a period character, although your regex is a bit more robust in detecting error when a non-ISO-conforming string is given.

1 Like