https://github.com/juliageo/cftime.jl

Julia library for decoding time units conforming to the Climate and Forecasting (CF) netCDF conventions.

https://github.com/juliageo/cftime.jl

Science Score: 100.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 4 DOI reference(s) in README and JOSS metadata
  • Academic publication links
    Links to: joss.theoj.org
  • Committers with academic emails
    1 of 8 committers (12.5%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
    Published in Journal of Open Source Software

Keywords

cf-conventions julia netcdf time

Keywords from Contributors

earth-observation meteorology climate-and-forecast-conventions climatology oceanography opendap julialang ode geo proj
Last synced: 4 months ago · JSON representation ·

Repository

Julia library for decoding time units conforming to the Climate and Forecasting (CF) netCDF conventions.

Basic Info
Statistics
  • Stars: 8
  • Watchers: 1
  • Forks: 1
  • Open Issues: 1
  • Releases: 13
Topics
cf-conventions julia netcdf time
Created over 6 years ago · Last pushed 5 months ago
Metadata Files
Readme License Citation

README.md

CFTime

documentation stable documentation latest

Build Status codecov DOI

CFTime encodes and decodes time units conforming to the Climate and Forecasting (CF) conventions. CFTime was split out of the NCDatasets Julia package.

Features of CFTime include:

  • Time instances as defined Climate and Forecasting (CF) conventions
  • Supporting a wide range of the time resolutions, from days down to attoseconds (for feature parity with NumPy's date time type)
  • Supporting arbitrary time origins. For CFTime.jl, the time origin is part of the parametric type definition and not an additional field of the time data structure. As a consequence, a large array of date times with common time origin only need to store the time counter (64-bit integer by default) for every element, which makes this case as memory efficient as NumPy's or Julia's default date time for this common use case.
  • By default, the time counter is a 64-bit integer, but other integers types (such as Int32, Int128 or BigInt) or floating-point types can be used. Using an integer to encode a time instance is recommended for most applications, as it makes reasoning about the time resolution easier.
  • Basic arithmetic such as computing the duration between two time instances
  • Conversion function between CFTime types and Julia's DateTime.
  • Regular time range based on Julia's range type. A time range is a vector of date time elements, but only the start time, the end time and the steps need to be stored in memory.

CFTime currently does not support leap seconds, which were standardized as part of CF conventions version 1.12, released in December 2024 and time zones.

Installation

Inside the Julia shell, you can download and install the package by issuing:

julia using Pkg Pkg.add("CFTime")

After installing the package, the test suite of CFTime can be run using:

julia Pkg.test("CFTime")

Example

For the Climate and Forecasting (CF) conventions, time is expressed as duration since starting time. The function CFTime.timedecode allows to convert these time instances as a Julia DateTime structure:

```julia using CFTime, Dates

standard calendar

dt = CFTime.timedecode([0,1,2,3],"days since 2000-01-01 00:00:00")

4-element Vector{Dates.DateTime}:

2000-01-01T00:00:00

2000-01-02T00:00:00

2000-01-03T00:00:00

2000-01-04T00:00:00

```

The function CFTime.timeencode does the inverse operation: converting a Julia DateTime structure to a duration since a start time:

```julia CFTime.timeencode(dt,"days since 2000-01-01 00:00:00")

4-element Vector{Float64}:

0.0

1.0

2.0

3.0

```

The CF conventions also allow for different calendars, for example a calendar where every months has a duration of 30 days:

```julia dt = CFTime.timedecode([0,1,2,3],"days since 2000-01-01 00:00:00",DateTime360Day)

4-element Vector{DateTime360Day{CFTime.Period{Int64, Val{86400}(), Val{0}()}, Val{(2000, 1, 1)}()}}:

2000-01-01T00:00:00

2000-01-02T00:00:00

2000-01-03T00:00:00

2000-01-04T00:00:00

CFTime.timeencode(dt,"days since 2000-01-01 00:00:00",DateTime360Day)

4-element Vector{Float64}:

0.0

1.0

2.0

3.0

`` You can replace in the example above the typeDateTime360Dayby the string"360_day"` (the name for the calendar according to the CF conventions).

Single time instances can also be created by calling the corresponding constructor function, e.g. DateTimeStandard for the standard calendar (mixed Gregorian/Julian calendar) in a similar way than Julias DateTime type. The units argument specifies the time resolutions (either day, hour, ... attosecond) for the common case where the duration is specified as an integer. For example, the 1 January 2000 + 1 ns would be:

```julia y,m,d = (2000,1,1) hour,minute,sec = (0,0,0) msec,µsec,nsec = (0,0,1) DateTimeStandard(y,m,d,hour,minute,sec,msec,µsec,nsec; units=:nanosecond)

DateTimeStandard(2000-01-01T00:00:00.000000001)

```

As in Julia's DateTime, the default time resolution is milliseconds. The duration are encoded internally as a 64-bit signed integer. High precision integer (or floating point numbers) can also be used, for example a 128-bit signed integer:

julia DateTimeStandard(Int128,y,m,d,hour,minute,sec,msec,µsec,nsec; units=:nanosecond)

The default time origin is currently 1 January 1900 00:00:00. A different time origin can be used by setting the origin parameter:

julia DateTimeStandard(Int128,y,m,d,hour,minute,sec,msec,µsec,nsec; units=:nanosecond, origin=(1970,1,1))

The units and origin argument can be wrapped as a Val to ensure that these values are known at compile-time:

julia DateTimeStandard(Int128,y,m,d,hour,minute,sec,msec,µsec,nsec; units=Val(:nanosecond), origin=Val((1970,1,1)))

Several compile-time optimization have been implemented for the particular but common case where date have the same time origin and/or the same time resolution.

Arithmetic operations (+,-) and comparision operators on these types are supported, for example:

```julia DateTimeStandard(2000,1,2) - DateTimeStandard(2000,1,1)

86400000 milliseconds

Dates.Day(DateTimeStandard(2000,1,2) - DateTimeStandard(2000,1,1))

1 day

DateTime360Day(2000,1,1) + Dates.Day(360)

DateTime360Day(2001-01-01T00:00:00)

DateTimeStandard(2000,1,2) > DateTimeStandard(2000,1,1)

true

```

Parsing dates

Dates can be parsed by using dateformat from Julia's Dates module, for example:

```julia dt = DateTimeNoLeap("21001231",dateformat"yyyymmdd");

or

dt = parse(DateTimeNoLeap,"21001231",dateformat"yyyymmdd")

Dates.year(dt),Dates.month(dt),Dates.day(dt)

output (2100, 12, 31)

```

Community guidelines

We aim to follow the community standards of the Julia project.

Before creating an issue, check whether the issue has not already been reported. When you file an issue, please include sufficient information that would allow somebody else to reproduce the issue, in particular: 1. Provide the code that generates the issue. 3. Make your code as simple as possible (while still showing the error and being runnable). 4. The full error message that you are seeing (in particular file names and line numbers of the stack-trace). 5. Which version of Julia and CFTime are you using? Please include the output of:

julia versioninfo() using Pkg Pkg.installed()["CFTime"]

For questions about the usage of CFTime, please create a topic in the Geo section of the Julia forum https://discourse.julialang.org/c/domain/geo/. Feel free to include CC @Alexander-Barth in your topic.

Contributions such as code or documentation are very welcomed! Here is an overview of the involved steps:

  • fork the repository
  • create a new branch with a meaningful name
  • implement the new feature or fix the issue
  • add a test case and documentation for new features
  • use the formatting tool runic
  • very that all tests pass locally
  • open the pull request with a brief description of the improvements to the code

For larger changes, it is recommended to open an issue first to better explain the purpose of the pull request.

Trivia

Microsoft Excel incorrectly considers 1900 as leap year. For example, the difference between the dates 1-Jan-2000 and 1-Jan-1900 are off by one day. This bug was subsequently preserved for compatibility and codified in the ISO/IEC 29500:2008 standard.

Alternatives

Julia packages:

Outside of the julia ecosystem:

Acknowledgments

Thanks to Jeff Whitaker and contributors for python's cftime released under the MIT license which has helped the development of this package by providing reference values and a reference implementation for tests. The algorithm is based on Jean Meeus' algorithm published in Astronomical Algorithms (2nd Edition, Willmann-Bell, p. 63, 1998) adapted to years prior to 300 AC.

Owner

  • Name: JuliaGeo
  • Login: JuliaGeo
  • Kind: organization

Geospatial packages for Julia

JOSS Publication

CFTime.jl: a Julia package for representing time following the Climate and Forecast conventions
Published
September 30, 2025
Volume 10, Issue 113, Page 8487
Authors
Alexander Barth ORCID
GHER, University of Liège, Liège, Belgium
Editor
Mengqi Zhao ORCID
Tags
julia climate-and-forecast-conventions oceanography meteorology earth-observation climatology netcdf

Citation (CITATION.bib)

@article{Barth2025,
  author = {Barth, Alexander},
  title = {CFTime.jl: a Julia package for representing time following the Climate and Forecast conventions},
  journal = {Journal of Open Source Software},
  year = {2025},
  publisher = {The Open Journal},
  volume = {10},
  number = {113},
  pages = {8487},
  doi = {10.21105/joss.08487},
  url = {https://doi.org/10.21105/joss.08487}
}

GitHub Events

Total
  • Create event: 11
  • Commit comment event: 10
  • Release event: 5
  • Issues event: 26
  • Watch event: 1
  • Delete event: 3
  • Issue comment event: 43
  • Push event: 162
  • Pull request event: 15
  • Fork event: 1
Last Year
  • Create event: 11
  • Commit comment event: 10
  • Release event: 5
  • Issues event: 26
  • Watch event: 1
  • Delete event: 3
  • Issue comment event: 43
  • Push event: 162
  • Pull request event: 15
  • Fork event: 1

Committers

Last synced: 4 months ago

All Time
  • Total Commits: 383
  • Total Committers: 8
  • Avg Commits per committer: 47.875
  • Development Distribution Score (DDS): 0.068
Past Year
  • Commits: 174
  • Committers: 4
  • Avg Commits per committer: 43.5
  • Development Distribution Score (DDS): 0.046
Top Committers
Name Email Commits
Alexander Barth b****r@g****m 357
dependabot[bot] 4****]@u****m 10
Martijn Visser m****r@g****m 5
Fabian Gans f****s@b****e 4
Haakon Ludvig Langeland Ervik 4****e@u****m 3
Rafael Schouten r****n@g****m 2
Julia TagBot 5****t@u****m 1
Yeesian Ng n****n@g****m 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 5 months ago

All Time
  • Total issues: 31
  • Total pull requests: 28
  • Average time to close issues: 3 months
  • Average time to close pull requests: 4 days
  • Total issue authors: 12
  • Total pull request authors: 7
  • Average comments per issue: 2.35
  • Average comments per pull request: 0.61
  • Merged pull requests: 26
  • Bot issues: 0
  • Bot pull requests: 12
Past Year
  • Issues: 19
  • Pull requests: 15
  • Average time to close issues: 19 days
  • Average time to close pull requests: 6 days
  • Issue authors: 4
  • Pull request authors: 4
  • Average comments per issue: 1.11
  • Average comments per pull request: 0.73
  • Merged pull requests: 13
  • Bot issues: 0
  • Bot pull requests: 5
Top Authors
Issue Authors
  • haakon-e (14)
  • rafaqz (6)
  • Alexander-Barth (2)
  • visr (1)
  • natgeo-wong (1)
  • st-bender (1)
  • mengqi-z (1)
  • kongdd (1)
  • meteorologytoday (1)
  • alextbradley (1)
  • rabernat (1)
  • JuliaTagBot (1)
Pull Request Authors
  • dependabot[bot] (12)
  • haakon-e (4)
  • rafaqz (4)
  • meggart (3)
  • visr (2)
  • Alexander-Barth (2)
  • JuliaTagBot (1)
Top Labels
Issue Labels
Pull Request Labels
dependencies (12) github_actions (3)

Packages

  • Total packages: 1
  • Total downloads:
    • julia 1,789 total
  • Total dependent packages: 18
  • Total dependent repositories: 0
  • Total versions: 13
juliahub.com: CFTime

Julia library for decoding time units conforming to the Climate and Forecasting (CF) netCDF conventions.

  • Versions: 13
  • Dependent Packages: 18
  • Dependent Repositories: 0
  • Downloads: 1,789 Total
Rankings
Dependent packages count: 5.4%
Dependent repos count: 9.9%
Average: 28.5%
Stargazers count: 45.1%
Forks count: 53.5%
Last synced: 4 months ago