Loss of precision with netcdf time when using datenum

조회 수: 3 (최근 30일)
mashtine
mashtine 2016년 2월 1일
댓글: mashtine 2016년 2월 16일
Hi there,
I am trying to read the time variable in from an netcdf file and convert it to datenum values but the end time always seems to fall short (26-11-2005 instead of 01-01-2006).
The time variable from the netcdf file is in 'days since 1860-01-01 00:00:00' and in '365_day' format but I am having trouble getting the proper datenum for the data. The time format is also 'double' precision so I am not sure why I am going wrong when I use the following for example:
time1980_05 = timestamp1980_05' + datenum('1860-01-01 00:00:00');
Any ideas?
  댓글 수: 1
Campion Loong
Campion Loong 2016년 2월 4일
Hi Mashtine,
It is a little difficult to know what's going on without some sample input and codes from your attempt. In general though, the datetime type (available for R2014b and up) is preferred to datenum - for one it has much better precision. You may want to give it a try.

댓글을 달려면 로그인하십시오.

채택된 답변

Kelly Kearney
Kelly Kearney 2016년 2월 4일
편집: Kelly Kearney 2016년 2월 4일
I wrote a function, daynoleap2datenum, that does the conversion that Peter suggested (in a slightly simpler manner... I just figure out which years need a leap day and bump the numbers up one at those locations). It converts the output to either datenumbers or datetime objects, so it can work regardless of Matlab version.
As you can see in this example, the missing leap days are what lead to your simple addition method coming up a bit short:
t = [0 58:60 364]';
t1 = datetime(2000,1,1) + t
t2 = daynoleap2datenum(t, 2000, 'dt')
t1 =
01-Jan-2000 00:00:00
28-Feb-2000 00:00:00
29-Feb-2000 00:00:00
01-Mar-2000 00:00:00
30-Dec-2000 00:00:00
t2 =
01-Jan-2000 00:00:00
28-Feb-2000 00:00:00
01-Mar-2000 00:00:00
02-Mar-2000 00:00:00
31-Dec-2000 00:00:00

추가 답변 (1개)

Peter Perkins
Peter Perkins 2016년 2월 4일
Mashtine, I'm not super familiar with netCDF, but "365 day format" and this
>> dt = between(datetime(2005,11,26),datetime(2006,1,1),'days')
dt =
36d
>> (2006-1860)/4
ans =
36.5
suggests that this is a leap day issue. I imagine you could solve this using datetime, if you have R2014b or later. This might be something like what you are looking for:
>> y = [datetime(1860,1,0) datetime(1860,2,28) + calyears(0:5)]
y =
Columns 1 through 6
31-Dec-1859 28-Feb-1860 28-Feb-1861 28-Feb-1862 28-Feb-1863 28-Feb-1864
Column 7
28-Feb-1865
>> % how many days from Feb 28 in year(i) to Feb 28 in year(i+1)
>> d = caldiff(y,'days')
d =
59d 366d 365d 365d 365d 366d
>> d = caldays(d)
d =
59 366 365 365 365 366
>> % which years have leap days?
>> hasLeapDay = (d == 366)
hasLeapDay =
0 1 0 0 0 1
>> adjust = cumsum(hasLeapDay)
adjust =
0 1 1 1 1 2
>> breakPoints = [1 cumsum(d)+1]
breakPoints =
1 60 426 791 1156 1521 1887
% try it out on some "365 day" dates
>> netcdfDay = [(58:61) (58:61)+365 (58:61)+2*365 (58:61)+3*365]
netcdfDay =
Columns 1 through 7
58 59 60 61 423 424 425
Columns 8 through 14
426 788 789 790 791 1153 1154
Columns 15 through 16
1155 1156
>> realDay = netcdfDay + discretize(netcdfDay,breakPoints,adjust)
>> realDay =
Columns 1 through 7
58 59 61 62 424 425 426
Columns 8 through 14
427 789 790 791 792 1154 1155
Columns 15 through 16
1156 1157
>> datestr(realDay + datenum([1860,1,0]))
ans =
27-Feb-1860
28-Feb-1860
01-Mar-1860
02-Mar-1860
27-Feb-1861
28-Feb-1861
01-Mar-1861
02-Mar-1861
27-Feb-1862
28-Feb-1862
01-Mar-1862
02-Mar-1862
27-Feb-1863
28-Feb-1863
01-Mar-1863
02-Mar-1863
  댓글 수: 5
Kelly Kearney
Kelly Kearney 2016년 2월 16일
The datetime object and associated functions were introduced in R2014b, so if you're running an older version, you won't be able to use Peter's code. But I really suggest giving my daynoleap2datenum function a try... it's pretty simple, version independent, and accounts for the 365-day calendar:
S = load('sampledata.mat');
dn = daynoleap2datenum(S.timestamp1980_05, 1860);
datestr(dn([1 end]))
ans =
01-Jan-1980 03:00:00
01-Jan-2006 00:00:00
mashtine
mashtine 2016년 2월 16일
Works! Thanks Kelly. Very useful code for me as I deal a lot with netcdf files.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Time Series Objects에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by