mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
Fixed bug NCF-175: ncdump -t incorrectly interpreting units attribute
(such as "days") without a base time (such as "since 2007-01-01") as a time unit.
This commit is contained in:
parent
d144438455
commit
024f318431
@ -327,7 +327,6 @@ cdParseRelunits(cdCalenType timetype, char* relunits, cdUnitTime* unit, cdCompTi
|
||||
} else {
|
||||
nconv = sscanf(relunits,"%s since %[^T]T%s",charunits,basetime_1,basetime_2);
|
||||
}
|
||||
|
||||
/* Get the units */
|
||||
cdTrim(charunits,CD_MAX_RELUNITS);
|
||||
if(!strncmp(charunits,"sec",3) || !strcmp(charunits,"s")){
|
||||
|
@ -108,6 +108,55 @@ is_bounds_var(char *varname, int *pargrpidp, int *parvaridp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Test if attribute is of form required by cdtime:
|
||||
* <time_unit> since <base_time>
|
||||
* where
|
||||
* <time_unit>:
|
||||
*/
|
||||
boolean
|
||||
is_valid_time_unit(const char *units) {
|
||||
char charunits[CD_MAX_RELUNITS];
|
||||
char basetime_1[CD_MAX_CHARTIME];
|
||||
char basetime_2[CD_MAX_CHARTIME];
|
||||
int nconv1, nconv2;
|
||||
boolean okunit = false;
|
||||
|
||||
/* Allow ISO-8601 "T" date-time separator as well as blank separator */
|
||||
nconv1 = sscanf(units,"%s since %[^T]T%s", charunits, basetime_1, basetime_2);
|
||||
nconv2 = sscanf(units,"%s since %s %s", charunits, basetime_1, basetime_2);
|
||||
if (!(nconv1 > 1 || nconv2 > 1))
|
||||
return false;
|
||||
/* Check for unit compatible with cdtime library, no attempt
|
||||
* to enforce CF-compliance or udunits compliance here ... */
|
||||
if(!strncmp(charunits,"sec",3) || !strcmp(charunits,"s")){
|
||||
okunit = true;
|
||||
}
|
||||
else if(!strncmp(charunits,"min",3) || !strcmp(charunits,"mn")){
|
||||
okunit = true;
|
||||
}
|
||||
else if(!strncmp(charunits,"hour",4) || !strcmp(charunits,"hr")){
|
||||
okunit = true;
|
||||
}
|
||||
else if(!strncmp(charunits,"day",3) || !strcmp(charunits,"dy")){
|
||||
okunit = true;
|
||||
}
|
||||
else if(!strncmp(charunits,"week",4) || !strcmp(charunits,"wk")){
|
||||
okunit = true;
|
||||
}
|
||||
else if(!strncmp(charunits,"month",5) || !strcmp(charunits,"mo")){
|
||||
okunit = true;
|
||||
}
|
||||
else if(!strncmp(charunits,"season",6)){
|
||||
okunit = true;
|
||||
}
|
||||
else if(!strncmp(charunits,"year",4) || !strcmp(charunits,"yr")){
|
||||
okunit = true;
|
||||
}
|
||||
if (!okunit)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return true only if this is a "bounds" attribute */
|
||||
boolean
|
||||
is_bounds_att(ncatt_t *attp) {
|
||||
@ -158,6 +207,10 @@ get_timeinfo(int ncid1, int varid1, ncvar_t *vp) {
|
||||
units = emalloc(uatt.len + 1);
|
||||
NC_CHECK(nc_get_att(ncid, varid, "units", units));
|
||||
units[uatt.len] = '\0';
|
||||
if(!is_valid_time_unit(units)) {
|
||||
free(units);
|
||||
return;
|
||||
}
|
||||
/* check for calendar attribute (not required even for time vars) */
|
||||
vp->timeinfo = (timeinfo_t *)emalloc(sizeof(timeinfo_t));
|
||||
memset((void*)vp->timeinfo,0,sizeof(timeinfo_t));
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
extern void insert_bounds_info(int ncid, int varid, ncatt_t att);
|
||||
extern int is_valid_time_unit(const char *units);
|
||||
extern int is_bounds_att(ncatt_t *attp);
|
||||
extern void get_timeinfo(int ncid, int varid, ncvar_t *vp);
|
||||
extern void print_att_times(int ncid, int varid, ncatt_t att);
|
||||
|
@ -82,6 +82,11 @@ variables:
|
||||
// "1804-04-26", "1804-04-27", "1804-04-28", "1804-04-29",
|
||||
// "1804-04-30"
|
||||
double t3_bnds(t3, bnds) ;
|
||||
int t4 ;
|
||||
t4:units = "days" ;
|
||||
t4:att1 = 1 ;
|
||||
t4:att2 = 5, 6 ;
|
||||
t4:att3 = 7.125f, 8.75f ;
|
||||
data:
|
||||
|
||||
t1_days = "2009-01-01" ;
|
||||
@ -132,4 +137,6 @@ data:
|
||||
"1804-01-10 12", "1804-01-11 12",
|
||||
"1804-01-11 12", "1804-01-12 12",
|
||||
"1804-01-12 12", "1804-01-13 12" ;
|
||||
|
||||
t4 = _ ;
|
||||
}
|
||||
|
@ -86,6 +86,13 @@ variables:
|
||||
t3:time5 = 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120 ;
|
||||
double t3_bnds(t3, bnds) ; // no attributes, since a cell bounds variable
|
||||
|
||||
// test -t bug fix, time unit without base time should not interpret numeric atts as times
|
||||
int t4 ;
|
||||
t4:units = "days" ;
|
||||
t4:att1 = 1 ;
|
||||
t4:att2 = 5, 6 ;
|
||||
t4:att3 = 7.125f, 8.75f ;
|
||||
|
||||
data:
|
||||
// Should all represent 2009-01-01 00:00:00
|
||||
t1_days = 185900;
|
||||
|
Loading…
Reference in New Issue
Block a user