add `unix2datetime(...; localtime)` functionality
Closes: #49297
I feel this implementation works well. I have also created a LOCALEPOCH variable so that a local functionality can be provided to other functions as well if required. Let me know if this is a good way, or the implementation must be different, or maybe creating a unix2datetime(x::Real; local::Bool=false) function to kind of merge both.
Also, I am bit confused about how I would write tests for this.
I substantially prefer the unix2datatime(x::Real; local::Bool=false) approach, personally. But thanks for trying to tackle this!
I am also thinking about making such changes to datetime2unix.
Maybe add a test that checks that the result matches the algorithm in this comment: https://github.com/JuliaLang/julia/issues/49297#issuecomment-1544247466
@stevengj, I was also wondering if I should implement such a functionality in other conversions as well, eg. julian2datetime and datetime2julian in this PR itself. Also, what do I need to do for the needs news tag?
It would be good to fix all of the xxxx2datetime functions at the same time, so that they retain a consistent API.
To update the news, you add a bullet item to the Dates subsection of NEWS.md, similar to the other NEWS items, and include it in this PR.
Relevant test failure:
Error During Test at /cache/build/default-amdci4-6/julialang/julia-master/julia-3b5e6ab110/share/julia/stdlib/v1.10/Dates/test/conversions.jl:46
| Test threw exception
| Expression: julian2datetime(1.7211195e6 - float(localunixdiff() / 86400000), localtime = true) == DateTime(0, 3, 1)
| UndefVarError: `value` not defined
Hopefully fixed by latest commit.
Looks like there's a related failure on macos
| Dates/conversions (12) \| failed at 2024-02-15T15:18:48.402
| Test Failed at /Users/julia/.julia/scratchspaces/a66863c6-20e8-4ff4-8a62-49f30b1f605e/agent-cache/default-honeycrisp-R17H3W25T9.0/build/default-honeycrisp-R17H3W25T9-0/julialang/julia-master/julia-0ab0c382c8/share/julia/stdlib/v1.11/Dates/test/conversions.jl:44
| Expression: unix2datetime(1.09537919875e9, localtime = true) == unix2localdatetime(1.09537919875e9)
| Evaluated: Dates.DateTime("2004-09-16T15:59:58.750") == Dates.DateTime("2004-09-16T16:59:58.750")
@IanButterworth that is a 1-hour difference … could the time zone have changed on the test machine while the test was running?
The timezone didn't change on the machine, the question posed is not consistent: since September and January are in different local timezones, you cannot go from one to the other simply by adding nanoseconds. In other words, LOCALEPOCH is not a consistent thing to have:
$ TZ=':America/New_York' ./julia -q
julia> (Dates.value(DateTime(Libc.TmStruct(180 * 24 * 60 * 60))) - Dates.UNIXEPOCH) / 3600_000 - 180 * 24
-4.0 hours in July
julia> (Dates.value(DateTime(Libc.TmStruct(360 * 24 * 60 * 60))) - Dates.UNIXEPOCH) / 3600_000 - 360 * 24
-5.0 hours in January
I'm good with the localtime keyword argument but another interface we could use here is:
unix2datetime(x::Real, ::Type{UTC}=UTC)
unix2datetime(x::Real, ::Type{Local})
Dates.jl already defines UTC (although it should probably be abstract) and we could define abstract type Local <: TimeZone end.