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

num2date returns 01:00:00 or 00:59:59 depending on calendar #54

Closed
demorym opened this issue Jul 10, 2018 · 6 comments
Closed

num2date returns 01:00:00 or 00:59:59 depending on calendar #54

demorym opened this issue Jul 10, 2018 · 6 comments

Comments

@demorym
Copy link

demorym commented Jul 10, 2018

Good afternoon,

Here is an issue I posted on Unidata/netcdf4-python#810 two weeks ago, and I have been advised to submit it here. Here it is below:

You may already be aware of this problem, but I didn't find how to solve it.
I have an output with hourly intervals written in days since 1979-01-01 00:00:00.
The first time step is 0. The second is 0.041666666667.
I have noticed that num2date does not give the same results when reading the second time step depending on the calendar used. It sometimes give 1979-01-01 01:00:00 (which is what we want), and sometimes 1979-01-01 00:59:59 (see below).
How can we fix it so num2date would give the correct result (01:00:00. 02:00:00, etc.) whatever calendar is used?

Thank you for your help,
Marie-Estelle

time_in1=0.041666666667
print(time_in_units)
days since 1979-01-01 00:00:00
dt_in1 = num2date(time_in1,time_in_units,calendar='standard')
str(dt_in1)
'1979-01-01 01:00:00'
dt_in1 = num2date(time_in1,time_in_units,calendar='gregorian')
str(dt_in1)
'1979-01-01 01:00:00'
dt_in1 = num2date(time_in1,time_in_units,calendar='proleptic_gregorian')
str(dt_in1)
'1979-01-01 01:00:00'
dt_in1 = num2date(time_in1,time_in_units,calendar='noleap')
str(dt_in1)
'1979-01-01 00:59:59'
dt_in1 = num2date(time_in1,time_in_units,calendar='365_day')
str(dt_in1)
'1979-01-01 00:59:59'
dt_in1 = num2date(time_in1,time_in_units,calendar='360_day')
str(dt_in1)
'1979-01-01 00:59:59'
dt_in1 = num2date(time_in1,time_in_units,calendar='julian')
str(dt_in1)
'1979-01-01 01:00:00'
dt_in1 = num2date(time_in1,time_in_units,calendar='all_leap')
str(dt_in1)
'1979-01-01 00:59:59'
dt_in1 = num2date(time_in1,time_in_units,calendar='366_day')
str(dt_in1)
'1979-01-01 00:59:59'

@jswhit
Copy link
Collaborator

jswhit commented Jul 13, 2018

Looks like a roundoff error - the accuracy of the calculation is around a millisecond.

@jswhit jswhit closed this as completed Jul 13, 2018
@jswhit jswhit reopened this Jul 13, 2018
@demorym
Copy link
Author

demorym commented Jul 13, 2018

Do you know how I could go around this?

@jswhit
Copy link
Collaborator

jswhit commented Jul 13, 2018

No, not without a rewrite of our julian day arithmetic to preserve more precision.

@jswhit
Copy link
Collaborator

jswhit commented Jul 13, 2018

Don't know whether this helps, but if you know the precision is 1 hour, you can do

d.strftime(format="%Y-%m-%d %H")

edited: never mind, that doesn't help - you'll get a zero printed for the hour.

@jswhit
Copy link
Collaborator

jswhit commented Jul 13, 2018

Adding a small offset to the time seems to do it, i.e.

>> d = cftime.num2date((1./24.)+1.e-6,'days since 1979-01-01 00:00:00',calendar='365_day')
>> print d

1979-01-01 01:00:00

@demorym
Copy link
Author

demorym commented Jul 17, 2018

It works indeed. Thank you so much for your help!

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