Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time calculation issue #9

Open
Breeze-Hu opened this issue Sep 6, 2024 · 2 comments
Open

Time calculation issue #9

Breeze-Hu opened this issue Sep 6, 2024 · 2 comments

Comments

@Breeze-Hu
Copy link

Hello, developers.

I'm using CFtime to do calculations on time and I'm finding inconsistencies with other software and packages (Panoply and python: xarray, cftime,).

R:

CFtime(“hours since 0001-01-01”, “standard”, 17181048)
#> CF datum of origin.
#> Origin : 0001-01-01 00:00:00
#> Units : hours
#> Calendar: standard
#>CF time series.
#> Elements: 1961-01-03 
#> Bounds : not set

Python:

import cftime
cftime.num2date(17181048, units="hours since 0001-01-01", calendar='standard')
#> cftime.DatetimeGregorian(1961, 1, 1, 0, 0, 0, 0, has_year_zero=False)

Other more detailed information can be found in this: Offset of “time” dim for terra packages when reading nc file

@pvanlaake
Copy link
Owner

pvanlaake commented Sep 6, 2024

Hello Breeze-Hu,

CFtime uses straight-up arithmetic for date-time calculations. Specifically also when using a standard calendar prior to the 1582-10-15 (when it was first introduced), disregarding the discontinuity, so effectively it is a proleptic_gregorian calendar. When looking at your numbers I get the following:

(17,181,048 / 24) - (1960 * 365) - (1960 / 4) + 15 = 2

Read that as offset divided by 24 hours gives the number of days, from which we subtract full years of 365 days, then we subtract leap days for every 4th year, but 15 century years (Y100, 200, 300, 500, etc) were not leaps years so we add those back, yields 2 resulting days. Add 2 to the difference in whole years gives 1961-01-03.

Python cftime does consider the discontinuity between the current gregorian calendar and the julian calendar in use before that (if I recall correctly, they use the underlying POSIX library). The julian calendar uses leap days but not the 100-less-400-year correction. Between Y0001 and Y1582 the difference between the julian and the proleptic_gregorian calendars is thus in the century leap years, of which there are 12: every century minus the 3 400-year centuries. The discontinuity between the two calendars was 10 days in 1582 (currently it is 13 days) and 12 - 10 = 2 days. So this is where the discrepancy comes from.

I noticed that you found the same discrepancy in some other packages, while others align with the xarray solution (great research!). So is CFtime (and the other software libraries that give the same result) wrong? Yes, from the perspective of using the standard calendar prior to 1582-10-15. No, from the perspective of there being many data sets out there that use the 0001-01-01 datum with a standard calendar which is thus really a proleptic_gregorian calendar. When looking at the CF Metadata Conventions, section 4.4.1, it is "recommended that a reference date/time before the discontinuity should not be used for date/times after the discontinuity, and vice-versa", so the problem is really with data producers that do not implement this recommendation.

There is currently no easy solution for this.

@Breeze-Hu
Copy link
Author

Wow! Very admirable!

There was exposure to bits and pieces of the difference between the two calendars in the last few days, but not a good understanding or calculation of how the difference between the two days got there. After your explanation I finally understand the reason for this result!

One calendar had 15 century years before 1582, again all leap years. But the other has only 400, 800 and 1200 years as leap years. There is a difference of 12 (=15-3) years in between.
In the year 1582, the Gregorian calendar lost about 10 days to the Julian calendar because the Gregorian calendar corrected for errors in the Julian calendar. The exact change occurred on October 4, 1582, the next day becoming October 15, so the two calendar systems created a 10-day difference at that point.
In the end, 12-10 = 2. This is the reason for the two-day difference in the final calculation.

Thank you very much for your reply! This solved my last two days of confusion. Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants