From e3ccc9d82b20a4efeef7734d98c610ece3e0f9f3 Mon Sep 17 00:00:00 2001 From: Fabian Gans Date: Wed, 21 Aug 2024 17:17:30 +0200 Subject: [PATCH] Factor out DateTime64 type (#145) * Factor out DateTime64 into dep * fix typestr parsing --- Project.toml | 2 ++ src/ZArray.jl | 6 ++++-- src/metadata.jl | 35 +++-------------------------------- 3 files changed, 9 insertions(+), 34 deletions(-) diff --git a/Project.toml b/Project.toml index 27c0cd9..77b6e11 100644 --- a/Project.toml +++ b/Project.toml @@ -9,6 +9,7 @@ Blosc = "a74b3585-a348-5f62-a45c-50e91977d574" CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +DateTimes64 = "b342263e-b350-472a-b1a9-8dfd21b51589" DiskArrays = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" @@ -24,6 +25,7 @@ AWSS3 = "0.10" Blosc = "0.5, 0.6, 0.7" CodecZlib = "0.6, 0.7" DataStructures = "0.17, 0.18" +DateTimes64 = "1" DiskArrays = "0.4.2" HTTP = "^1.3" JSON = "0.21" diff --git a/src/ZArray.jl b/src/ZArray.jl index 1cd7255..acbf23e 100644 --- a/src/ZArray.jl +++ b/src/ZArray.jl @@ -2,6 +2,8 @@ import JSON import OffsetArrays: OffsetArray import DiskArrays: AbstractDiskArray import DiskArrays +using DateTimes64: DateTime64 +using Dates: Day, Millisecond """ Number of tasks to use for async reading of chunks. Warning: setting this to very high values can lead to a large memory footprint. @@ -372,8 +374,8 @@ filterfromtype(::Type{<:Union{MaxLengthString, Union{MaxLengthString, Missing}}} #Not all Array types can be mapped directly to a valid ZArray encoding. #Here we try to determine the correct element type to_zarrtype(::AbstractArray{T}) where T = T -to_zarrtype(a::AbstractArray{<:Date}) = DateTime64{Dates.Day} -to_zarrtype(a::AbstractArray{<:DateTime}) = DateTime64{Dates.Millisecond} +to_zarrtype(a::AbstractArray{<:Date}) = DateTime64{Day} +to_zarrtype(a::AbstractArray{<:DateTime}) = DateTime64{Millisecond} function ZArray(a::AbstractArray, args...; kwargs...) z = zcreate(to_zarrtype(a), args..., size(a)...; kwargs...) diff --git a/src/metadata.jl b/src/metadata.jl index c7660e7..f3dc5df 100644 --- a/src/metadata.jl +++ b/src/metadata.jl @@ -1,4 +1,5 @@ import Dates: Date, DateTime +using DateTimes64: DateTime64, pydatetime_string, datetime_from_pystring """NumPy array protocol type string (typestr) format @@ -21,37 +22,7 @@ Base.codepoint(x::ASCIIChar) = UInt8(x) Base.show(io::IO, x::ASCIIChar) = print(io, Char(x)) Base.zero(::Union{ASCIIChar,Type{ASCIIChar}}) = ASCIIChar(Base.zero(UInt8)) - -using Dates: Period, TimeType, Date, DateTime, Dates -import Base.== -struct DateTime64{P} <: TimeType - i::Int64 -end -Base.convert(::Type{Date},t::DateTime64{P}) where P = Date(1970)+P(t.i) -Base.convert(::Type{DateTime},t::DateTime64{P}) where P = DateTime(1970)+P(t.i) -Base.show(io::IO,t::DateTime64{P}) where P = print(io,"DateTime64[",P,"]: ",string(DateTime(t))) -Base.isless(x::DateTime64{P}, y::DateTime64{P}) where P = isless(x.i, y.i) -==(x::DateTime64{P}, y::DateTime64{P}) where P = x.i == y.i -strpairs = [Dates.Year => "Y", Dates.Month => "M", Dates.Week => "W", Dates.Day=>"D", - Dates.Hour => "h", Dates.Minute => "m", Dates.Second=>"s", Dates.Millisecond =>"ms", - Dates.Microsecond => "us", Dates.Nanosecond => "ns"] -const jlperiod = Dict{String,Any}() -const pdt64string = Dict{Any, String}() -for p in strpairs - jlperiod[p[2]] = p[1] - pdt64string[p[1]] = p[2] -end -Base.convert(::Type{DateTime64{P}}, t::Date) where P = DateTime64{P}(Dates.value(P(t-Date(1970)))) -Base.convert(::Type{DateTime64{P}}, t::DateTime) where P = DateTime64{P}(Dates.value(P(t-DateTime(1970)))) -Base.convert(::Type{DateTime64{P}}, t::DateTime64{Q}) where {P,Q} = DateTime64{P}(Dates.value(P(Q(t.i)))) -Base.zero(t::Union{DateTime64, Type{<:DateTime64}}) = t(0) Base.zero(t::Union{String, Type{String}}) = "" -# Base.promote_rule(::Type{<:DateTime64{<:Dates.DatePeriod}}, ::Type{Date}) = Date -# Base.promote_rule(::Type{<:DateTime64{<:Dates.DatePeriod}}, ::Type{DateTime}) = DateTime -# Base.promote_rule(::Type{<:DateTime64{<:Dates.TimePeriod}}, ::Type{Date}) = DateTime -# Base.promote_rule(::Type{<:DateTime64{<:Dates.TimePeriod}}, ::Type{DateTime}) = DateTime - - typestr(t::Type) = string('<', 'V', sizeof(t)) typestr(t::Type{>:Missing}) = typestr(Base.nonmissingtype(t)) @@ -63,7 +34,7 @@ typestr(t::Type{<:AbstractFloat}) = string('<', 'f', sizeof(t)) typestr(::Type{MaxLengthString{N,UInt32}}) where N = string('<', 'U', N) typestr(::Type{MaxLengthString{N,UInt8}}) where N = string('<', 'S', N) typestr(::Type{<:Array}) = "|O" -typestr(::Type{<:DateTime64{P}}) where P = "])([tbiufcmMOSUV])(\d*)(\[\w+\])?$" @@ -107,7 +78,7 @@ function typestr(s::AbstractString, filterlist=nothing) end if tc == 'M' && ts == 8 #We have a datetime64 value - return DateTime64{jlperiod[String(typespec)[2:end-1]]} + return datetime_from_pystring(s) end # convert typecode to Char and typesize to Int typemap[(tc,ts)]