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.
Hi Russ, Here's an updated version of read.ncdump.c (attached) that shouldn't elicit complaints from most compilers (or at least reduce the number of major complaints). I could have corrected my mistakes a while back, but better late than never, I suppose. Cheers, Rick Danielson On Thu, 25 Mar 2004, Russ Rew wrote: > >To: address@hidden > >From: <address@hidden> > >Subject: ncdump dates (fwd) > >Organization: CMC > >Keywords: 200403241452.i2OEqsrV029902 ncdump > > Hi Rick, > > > Earlier in the month I sent the message below directly to the > > netcdfgroup. I don't usually submit to the group, and perhaps I should > > have sent it to support instead. Anyway, I'll re-send, just in case I > > goofed: > > I didn't see it on the netcdfgroup mailing list, so maybe it got > filtered out for some reason (such as having an attachment), or you > sent it from a different email address than used for you on the > netcdfgroup mailing list. > > > A version of ncdump at the CDC used to convert udunits dates into > > dates that can be read easily. I lost that functionality recently (and > > CDC ncdump was hard to compile using a newer version of netCDF), and wrote > > a short program to replace it. The idea is to filter the output of ncdump > > and replace the dates using udunits. It seems to work for NCEP Reanalysis > > data files. I've included a perl script below that illustrates how it > > could be used on multiple netCDF files, for example. The "read.ncdump.c" > > program is attached, in case there are others in the same boat (I doubt > > it's COARDS compliant, but that could be changed). > > > > Cheers, > > Rick Danielson > > > > #!/usr/bin/perl -w > > for ($a = 0; $a < scalar(@ARGV); $a++) { > > $command = "ncdump -c $ARGV[$a] | read.ncdump\n"; > > system($command); > > } > > Thanks for contributing this! I copied it to our contributed netCDF > software directory: > > ftp://ftp.unidata.ucar.edu/pub/netcdf/contrib/read.ncdump.c > > and added an entry about it in our contributed software catalog: > > http://www.unidata.ucar.edu/packages/netcdf/Contrib.html > > that says: > > read.ncdump.c > Rick Danielson's filter for ncdump output that replaces udunits > times with the corresponding date and time in a more readable > form YYYY-MM-DD hh:mm:ss. > > If you want to change this, just let me know. It still might be > worthwhile to announce this on the netcdfgroup mailing list, as there > might be others who would like to know about your filter. > > --Russ > > _____________________________________________________________________ > > Russ Rew UCAR Unidata Program > address@hidden http://www.unidata.ucar.edu/staff/russ > > >
/* * filter the result of ncdump to output time information - RD February 2004 * * Use the output of ncdump as the input to this program. For example, this perl script * could be used on multiple netCDF files to replace dates with something more readable: * * #!/usr/bin/perl -w * for ($a = 0; $a < scalar(@ARGV); $a++) { * $command = "ncdump -c $ARGV[$a] | read.ncdump\n"; * system($command); * } * */ #include <stdio.h> #include <math.h> #include <unistd.h> #include "/home/danielsonr/soft/udunits/include/udunits.h" #define LEN 99 /* * Please note that a "segmentation error" may occur owing to a * liberal use of memory here. If this occurs, a reduction of * LOTS(=9999 or so) may be in order. */ #define LOTS 33333 #define DIMS 0 #define VARS 1 #define DATA 2 void datestr(char date[], int yr, int mo, int dy, int hr, int mn, int sc); int main(int argc, char *argv[]) { FILE *fpa, *fpb, *fopen(); int a, b, c, d, year, month, day, hour, minute, section; char line[LOTS], date[LEN], times[LOTS][LEN], valstr[LEN]; float second; char udunita[LEN], udunitb[LEN]; /* udunits declarations */ utUnit utunita, utunitb; float value; if (argc != 1) { printf("Usage: %s\n",argv[0]); exit(1); } if (utInit("") != 0) { printf("couldn't initialize Unidata units library\n"); exit(2); } while (fgets(line,LOTS,stdin) != NULL) { /* for each ncdump output line */ if (strstr(line,"dimensions:") != NULL) section = DIMS; /* note the section being printed */ if (strstr(line,"variables:") != NULL) section = VARS; if (strstr(line,"data:") != NULL) section = DATA; if (section == VARS && strstr(line,"time:units") != NULL) { printf("%s",line); strtok(line,"\""); strcpy(udunita,(char *)strtok(NULL,"\"")); utScan(udunita,&utunita); } else if (section == VARS && strstr(line,"time:actual_range") != NULL) { strtok(line,"=,;"); strcpy(valstr,(char *)strtok(NULL,"=,;")); sscanf(valstr,"%f",&value); utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second); datestr(date,year,month,day,hour,minute,second); printf("%s= \"%s, ",line,date); strcpy(valstr,(char *)strtok(NULL,"=,;")); sscanf(valstr,"%f",&value); utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second); datestr(date,year,month,day,hour,minute,second); printf("%s\"\n",date); } else if (section == VARS && strstr(line,"time:ltm_range") != NULL) { strtok(line,"=,;"); strcpy(valstr,(char *)strtok(NULL,"=,;")); sscanf(valstr,"%f",&value); utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second); datestr(date,year,month,day,hour,minute,second); printf("%s= \"%s, ",line,date); strcpy(valstr,(char *)strtok(NULL,"=,;")); sscanf(valstr,"%f",&value); utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second); datestr(date,year,month,day,hour,minute,second); printf("%s\"\n",date); } else if (section == DATA && strstr(line,"time =") != NULL) { while (strstr(line,";") == NULL) { fgets(valstr,LEN,stdin); strcat(line,valstr); } strcpy(valstr,(char *)strtok(line,"=,")); a = 0; while (strstr(valstr,";") == NULL) { strcpy(valstr,(char *)strtok(NULL,"=,")); sscanf(valstr,"%f",&value); utCalendar(value,&utunita,&year,&month,&day,&hour,&minute,&second); datestr(date,year,month,day,hour,minute,second); strcpy(times[a],date); a++; } printf(" time = "); b = c = 0; while (b < a) { printf("%s",times[b]); if (b == a-1) printf(" ;\n"); else if (c == 2) { printf(",\n "); c = -1; } else printf(", "); b++; c++; } } else { printf("%s",line); } } fclose(fpa); return(0); } void datestr(char date[], int yr, int mo, int dy, int hr, int mn, int sc) { char num[LEN]; sprintf(num,"%d",yr); if (yr < 10) strcpy(date,"000"); else if (yr < 100) strcpy(date,"00"); else if (yr < 1000) strcpy(date,"0"); else strcpy(date,""); strcat(date,num); strcat(date,"-"); sprintf(num,"%d",mo); if (mo < 10) strcat(date,"0"); strcat(date,num); strcat(date,"-"); sprintf(num,"%d",dy); if (dy < 10) strcat(date,"0"); strcat(date,num); strcat(date," "); sprintf(num,"%d",hr); if (hr < 10) strcat(date,"0"); strcat(date,num); strcat(date,":"); sprintf(num,"%d",mn); if (mn < 10) strcat(date,"0"); strcat(date,num); strcat(date,":"); sprintf(num,"%d",sc); if (sc < 10) strcat(date,"0"); strcat(date,num); }