juliageo / cftime.jl Goto Github PK
View Code? Open in Web Editor NEWJulia library for decoding time units conforming to the Climate and Forecasting (CF) netCDF conventions.
Home Page: http://juliageo.org/CFTime.jl/
License: MIT License
Julia library for decoding time units conforming to the Climate and Forecasting (CF) netCDF conventions.
Home Page: http://juliageo.org/CFTime.jl/
License: MIT License
Describe the bug
Some netcdf files produced by python's xarray
have time units nanoseconds since <datetime>
.
Those are not yet handled by NCDataset via CFTime (Alexander-Barth/NCDatasets.jl#192).
Supporting additional second subdivisions in timedecode()
would be appreciated, such as microsecond
and nanosecond
. This would also be consistent with python's handling, see Alexander-Barth/NCDatasets.jl#181 (comment).
To Reproduce
julia> using CFTime
julia> timedecode(1e9, "nanoseconds since 2000-01-01 00:00:00.001", "proleptic_gregorian")
ERROR: unknown units nanoseconds
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] timeunits(#unused#::Type{DateTimeProlepticGregorian}, units::String)
@ CFTime ~/.julia/packages/CFTime/n09Um/src/CFTime.jl:446
[3] timedecode(#unused#::Type{DateTimeProlepticGregorian}, data::Float64, units::String)
@ CFTime ~/.julia/packages/CFTime/n09Um/src/CFTime.jl:494
[4] timedecode(data::Float64, units::String, calendar::String; prefer_datetime::Bool)
@ CFTime ~/.julia/packages/CFTime/n09Um/src/CFTime.jl:545
[5] timedecode(data::Float64, units::String, calendar::String)
@ CFTime ~/.julia/packages/CFTime/n09Um/src/CFTime.jl:543
[6] top-level scope
@ REPL[6]:1
Expected behavior
Same result as with seconds
:
julia> timedecode(1, "seconds since 2000-01-01 00:00:00.001", "proleptic_gregorian")
2000-01-01T00:00:01.001
Environment
It would be good to not have to specify this when automating conversions.
Edit: I may misunderstand exactly how this works... The end goal is to have reciprocal conversion to/from vectors of time types to strings without having to specify anything besides the DateTime objects so that NCDatasets can load and save vars of AbstractCFDateTime
without and special casing. This is required for load/save to be easy and seemless in GeoData.jl.
I would like to get time periods in julia DatePeriod
object like Month(1)
from netcdf time dimension delta_t
fields like "0000-01-00 00:00:00"
. This would give correct time ranges in GeoData.jl.
Are there tools here that would already do that, or get some of the way?
Describe the bug
The handling of year 0 changed in python cftime:
10/1/2021: Version 1.5.1 released. Changed default behavior of proleptic_gregorian to has_year_zero=T
(since it is allowed in ISO-8601 and CF does not specify the year zero convention for this calendar).
Raise warning message when trying to create a calendar that is not supported by CF version 1.9
(no years < 1 allowed for 'standard'/'gregorian' or 'julian' calendars).
To Reproduce
using CFTime, Dates
DateTimeProlepticGregorian(1,1,1) - Day(1)
# output: DateTimeProlepticGregorian(-001-12-31T00:00:00)
All calendars are affected expect DateTimeStandard and DateTimeJulian
Expected behavior
output should be DateTimeProlepticGregorian(0,12,31)
as in python:
In [3]: cftime.DatetimeProlepticGregorian(1, 1, 1) + timedelta(days=-1)
Out[3]: cftime.DatetimeProlepticGregorian(0, 12, 31, 0, 0, 0, 0, has_year_zero=True)
Environment
Full output
No additional output. All reference values from python and cftime 1.6.0:
In [3]: cftime.DatetimeProlepticGregorian(1, 1, 1) + timedelta(days=-1)
Out[3]: cftime.DatetimeProlepticGregorian(0, 12, 31, 0, 0, 0, 0, has_year_zero=True)
In [4]: cftime.DatetimeJulian(1, 1, 1) + timedelta(days=-1)
<ipython-input-4-e85e1427bb46>:1: CFWarning: this date/calendar/year zero convention is not supported by CF
cftime.DatetimeJulian(1, 1, 1) + timedelta(days=-1)
Out[4]: cftime.DatetimeJulian(-1, 12, 31, 0, 0, 0, 0, has_year_zero=False)
In [5]: cftime.DatetimeGregorian(1, 1, 1) + timedelta(days=-1)
<ipython-input-5-d72578c40af5>:1: CFWarning: this date/calendar/year zero convention is not supported by CF
cftime.DatetimeGregorian(1, 1, 1) + timedelta(days=-1)
Out[5]: cftime.DatetimeGregorian(-1, 12, 31, 0, 0, 0, 0, has_year_zero=False)
In [6]: cftime.DatetimeAllLeap(1, 1, 1) + timedelta(days=-1)
Out[6]: cftime.DatetimeAllLeap(0, 12, 31, 0, 0, 0, 0, has_year_zero=True)
In [7]: cftime.DatetimeNoLeap(1, 1, 1) + timedelta(days=-1)
Out[7]: cftime.DatetimeNoLeap(0, 12, 31, 0, 0, 0, 0, has_year_zero=True)
In [8]: cftime.Datetime360Day(1, 1, 1) + timedelta(days=-1)
Out[8]: cftime.Datetime360Day(0, 12, 30, 0, 0, 0, 0, has_year_zero=True)
Running the function daysinmonth of month 2 gives error:
julia> daysinmonth(DateTimeNoLeap, 2)
ERROR: MethodError: no method matching rem(::Type{DateTimeNoLeap}, ::Int64)
Closest candidates are:
rem(::Any, ::Any, ::RoundingMode{:ToZero}) at div.jl:67
rem(::Any, ::Any, ::RoundingMode{:Down}) at div.jl:68
rem(::Any, ::Any, ::RoundingMode{:Up}) at div.jl:69
...
Stacktrace:
[1] isleapyear(y::Type)
@ Dates /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/Dates/src/types.jl:159
[2] daysinmonth(y::Type, m::Int64)
@ Dates /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/Dates/src/types.jl:163
[3] top-level scope
@ REPL[12]:1
But other months work fine
julia> daysinmonth(DateTimeNoLeap, 1)
31
julia> daysinmonth(DateTimeNoLeap, 3)
31
julia> daysinmonth(DateTimeNoLeap, 4)
30
julia> daysinmonth(DateTimeNoLeap, 5)
31
julia> daysinmonth(DateTimeNoLeap, 6)
30
julia> daysinmonth(DateTimeNoLeap, 7)
31
julia> daysinmonth(DateTimeNoLeap, 8)
31
julia> daysinmonth(DateTimeNoLeap, 9)
30
julia> daysinmonth(DateTimeNoLeap, 10)
31
julia> daysinmonth(DateTimeNoLeap, 11)
30
I am using CFTime v0.1.1 of Julia version 1.6.1 on CentOS stream 8.
Describe the bug
In GFDL model output, if absolute time is not important, a very commonly used option is to select the time option to be "NO_CALENDAR", which therefore has the following options as seen in the below example when using NCDatasets:
time (360)
Datatype: Float64
Dimensions: time
Attributes:
long_name = time
units = days since 0000-00-00 00:00:00
cartesian_axis = T
calendar_type = NO_CALENDAR
calendar = NO_CALENDAR
bounds = time_bounds
I cannot use NCDatasets.jl
to read the time
variable, because then it gives me:
ERROR: Unsupported calendar: no_calendar
Stacktrace:
[1] error(::String) at ./error.jl:33
[2] timetype(::String) at /Users/natgeo-wong/.julia/packages/CFTime/T83bb/src/CFTime.jl:594
[3] timeunits(::String, ::String) at /Users/natgeo-wong/.julia/packages/CFTime/T83bb/src/CFTime.jl:610
[4] getindex(::NCDataset, ::String) at /Users/natgeo-wong/.julia/packages/NCDatasets/Tb4eK/src/cfvariable.jl:281
[5] top-level scope at none:0
Request
Is it possible to add a "NO_CALENDAR" option/struct to CFTime
to accommodate model output?
I need to parse "21001231" into Date
with the calender type of 365_day
(DateTimeNoLeap
).
Any idea how to do that?
Thank u.
Describe the bug
The year 300, which is not a leap year, has some odd behavior in the proleptic Gregorian calendar. Instead of going from February 28 to March 1, it goes from February 28 to February 29 to March 2, so March 1 is missing and replaced by a non existing leap day.
To Reproduce
using Dates, CFTime
isleapyear(300) # false
isleapyear(304) # true
daysinmonth(DateTimeProlepticGregorian, 300, 2) # 28
Date(300, 2, 29) # error: cannot create non existing day
g = DateTimeProlepticGregorian(300, 2, 29) # can create in proleptic Gregorian
g = DateTimeProlepticGregorian(300, 3, 1) # this creates the same day, February 29
g + Day(1) # next day is March 2
DateTimeProlepticGregorian(2022, 1, 32) # note that this creates February 1, not sure if desired
Expected behavior
I expect DateTimeProlepticGregorian(300, 2, 29)
to error, or if desired create March 1.
Environment
CFTime v0.1.1
Sorry for not providing a fully reproducible example. I'm new to Julia.
When I call
using PyPlot
plot(time, timeseries)
where time
is a Array{DateTimeNoLeap,1}
object, I get this error:
Cannot convert DateTimeNoLeap to series data for plotting
Stacktrace:
[1] error(::String) at ./error.jl:33
[2] prepareSeriesData(::DateTimeNoLeap) at /Users/rpa/.julia/packages/Plots/2KhB2/src/series.jl:14
[3] convertToAnyVector(::DateTimeNoLeap, ::Dict{Symbol,Any}) at /Users/rpa/.julia/packages/Plots/2KhB2/src/series.jl:26
[4] (::Plots.var"#151#154"{Dict{Symbol,Any}})(::DateTimeNoLeap) at ./none:0
[5] iterate(::Base.Generator{Array{DateTimeNoLeap,1},Plots.var"#151#154"{Dict{Symbol,Any}}}) at ./generator.jl:47
[6] convertToAnyVector(::Array{DateTimeNoLeap,1}, ::Dict{Symbol,Any}) at /Users/rpa/.julia/packages/Plots/2KhB2/src/series.jl:41
[7] macro expansion at /Users/rpa/.julia/packages/Plots/2KhB2/src/series.jl:129 [inlined]
[8] apply_recipe(::Dict{Symbol,Any}, ::Type{Plots.SliceIt}, ::Array{DateTimeNoLeap,1}, ::Array{Float32,1}, ::Nothing) at /Users/rpa/.julia/packages/RecipesBase/zBoFG/src/RecipesBase.jl:275
[9] _process_userrecipes(::Plots.Plot{Plots.GRBackend}, ::Dict{Symbol,Any}, ::Tuple{Array{DateTimeNoLeap,1},Array{Float32,1}}) at /Users/rpa/.julia/packages/Plots/2KhB2/src/pipeline.jl:83
[10] _plot!(::Plots.Plot{Plots.GRBackend}, ::Dict{Symbol,Any}, ::Tuple{Array{DateTimeNoLeap,1},Array{Float32,1}}) at /Users/rpa/.julia/packages/Plots/2KhB2/src/plot.jl:178
[11] #plot#137(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(plot), ::Array{DateTimeNoLeap,1}, ::Vararg{Any,N} where N) at /Users/rpa/.julia/packages/Plots/2KhB2/src/plot.jl:57
[12] plot(::Array{DateTimeNoLeap,1}, ::Array{Float32,1}) at /Users/rpa/.julia/packages/Plots/2KhB2/src/plot.jl:51
[13] top-level scope at In[120]:3
Is there a recommended way to plot with CFTime object?
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
If you'd like for me to do this for you, comment TagBot fix
on this issue.
I'll open a PR within a few hours, please be patient!
Requiring strings for the calendar type means the calling code has to convert the type to string if it want to encode the same calendar type.
I think adding timetype(dt::Type{<:AbstractCFDateTime}) = dt
would acheive this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.