This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
Manuel, > To: address@hidden > From: Manuel Fuentes <address@hidden> > Subject: [Fwd: udunits question] > Organization: ECMWF > Keywords: 200404301801.i3UI1XtK021522 The above message contained the following: > I'm coding some seasonal forecast monthly mean data > in NetCDF, and I'm facing some problems when ncview > displays the month of data. I code it as: > "months since 1975-11-01 00:00:00.0"; > then months are 1, 2, 3, 4, 5 and 6 (I attach how the > netcdf file looks like: nc.header). > > I've tracked the problem down to udunits 1.12.1. > I have prepared a test case in C (ud.c). I compile it with: > cc -g -I/usr/local/apps/udunits/current/include -c ud.c > cc -g -L/usr/local/apps/udunits/current/lib ud.o -o ud -ludunits -lc -lm > I'm using udunits 1.12.1. > > I expect it to give consecutive months, but instead it > repeats December and jumps over February. > leda:~/src/udunits) ./ud 1 > month: 12, Dec-1975 > leda:~/src/udunits) ./ud 2 > month: 12, Dec-1975 > leda:~/src/udunits) ./ud 3 > month: 1, Jan-1976 > leda:~/src/udunits) ./ud 4 > month: 3, Mar-1976 > leda:~/src/udunits) ./ud 5 > month: 4, Apr-1976 > leda:~/src/udunits) ./ud 6 > month: 5, May-1976 > > Do you have any suggestions how could I solve this problem ? Unfortunately, a "month" is not a very good unit as the amount of time it represents depends on the month. Units aren't supposed to vary. The "month" unit used by the UDUNITS package is the mean tropical month, which is a fixed amount of time. This can lead to the problem you encounted when such "units" are used too simply. You can see what the UDUNITS package is doing by changing the statement printf("month: %d, %s-%04d\n", month,months[month-1], year ); to something like printf("year=%d month=%d day=%d hour=%d minute=%d\n", year, month, day, hour, minute); How you "solve" the "problem" depends on what you want to do with the time domain. In general, you'll need to be more sophisticated in your handling of time (i.e., you'll have to write more code). This is unfortunate, but unavoidable. Sorry. > Thanks in advance for your help, > Manuel Fuentes > Senior Analyst, Data and Services Section > European Centre for Medium-Range Weather Forecasts (ECMWF) > Shinfield Park, Reading, Berks RG2 9AX, England > > > --------------040406020507040803020702 > Content-Type: text/plain; > name="nc.header" > Content-Transfer-Encoding: 7bit > Content-Disposition: inline; > filename="nc.header" > > netcdf output { > dimensions: > longitude = 31 ; > latitude = 19 ; > number = 3 ; > fcmonth = 6 ; > variables: > float longitude(longitude) ; > longitude:units = "degrees_east" ; > longitude:long_name = "longitude" ; > float latitude(latitude) ; > latitude:units = "degrees_north" ; > latitude:long_name = "latitude" ; > int number(number) ; > number:long_name = "ensemble_member" ; > int fcmonth(fcmonth) ; > fcmonth:units = "months since 1975-11-01 00:00:00.0" ; > fcmonth:long_name = "Time" ; > short z(fcmonth, number, latitude, longitude) ; > z:scale_factor = 0.0647855851250515 ; > z:add_offset = 13909.0965134574 ; > z:_FillValue = -32767s ; > z:units = "m**2 s**-2" ; > z:long_name = "Geopotential" ; > char MARS ; > MARS:date = "19751101" ; > MARS:time = "0000" ; > MARS:step = "0" ; > MARS:class = "dm" ; > MARS:levtype = "pl" ; > MARS:levelist = "850" ; > MARS:domain = "g" ; > > // global attributes: > :Conventions = "CF-1.0" ; > :history = "2004-04-30 16:25:00 GMT by mars2netcdf-0.91" ; > data: > > longitude = -30, -27.5, -25, -22.5, -20, -17.5, -15, -12.5, -10, -7.5, -5, > -2.5, 0, 2.5, 5, 7.5, 10, 12.5, 15, 17.5, 20, 22.5, 25, 27.5, 30, 32.5, > 35, 37.5, 40, 42.5, 45 ; > > latitude = 75, 72.5, 70, 67.5, 65, 62.5, 60, 57.5, 55, 52.5, 50, 47.5, 45, > 42.5, 40, 37.5, 35, 32.5, 30 ; > > number = 0, 1, 2 ; > > fcmonth = 1, 2, 3, 4, 5, 6 ; > > > > --------------040406020507040803020702 > Content-Type: text/plain; > name="ud.c" > Content-Transfer-Encoding: 7bit > Content-Disposition: inline; > filename="ud.c" > > #include <stdio.h> > #include <stdlib.h> > #include <udunits.h> > > int main(int argc, char *argv[]) > { > utUnit dataunits; > double newmonth=2.0; > int year, month, day, hour, minute; > float second; > static char *months[12] = { > "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; > char *units = "months since 1975-11-01 00:00:00.0"; > int i = 0; > > if(argc==2) > newmonth = (double)atof(argv[1]); > > utInit(NULL); > if(utScan(units,&dataunits) != 0) > { > printf("internal error: udu_fmt_time can't parse data unit > string!\n" ); > printf("problematic units: \"%s\"\n", units ); > exit( -1 ); > } > > if(utCalendar( newmonth, &dataunits, &year, &month, &day, &hour, > &minute, &second ) != 0) > { > printf("internal error: udu_fmt_time can't convert to calendar > value!\n"); > printf("units: >%s<\n", units ); > exit( -1 ); > } > > printf("month: %d, %s-%04d\n", month,months[month-1], year ); > return 0; > } Regards, Steve Emmerson > NOTE: All email exchanges with Unidata User Support are recorded in the > Unidata inquiry tracking system and then made publically available > through the web. If you do not want to have your interactions made > available in this way, you must let us know in each email you send to us.