Reading Calendar Data From a File
QUESTION: I have time and calendar data in a file, along with other data values in a text file. (See the example data below.) What is the best way to read these calendar and data values out of the file?
23-03-2002 16:11:33.000 1.57100 -8.41400 -4.89800 23-03-2002 16:11:49.000 1.57200 -8.60200 -4.59500 23-03-2002 16:12:05.000 1.00100 -8.48400 -5.06300 23-03-2002 16:12:21.000 0.80600 -8.38700 -5.26600
ANSWER: The easiest way to read the time or calendar data is to read it using calendar formatting C() codes. (See "format codes" in the IDL on-line help for more details describing the calendar codes.) The advantage of reading the data like this, is that the time data will be stored in a Julian day number, which can then be output in various other formats (again, using the calendar formatting codes) or plotted directly on time axes.
Consider just the first line in your example data file.
IDL> dataLine = '23-03-2002 16:11:33.000 1.57100 -8.41400 -4.89800' IDL> time = 0D IDL> values = FltArr(3) IDL> timeformat = '(C(CDI,x,CMOI,x,CYI,x,CHI,x,CMI,x,CSF,x),3G0)' IDL> ReadS, dataLine, time, values, Format=timeformat IDL> Help, time TIME DOUBLE = 2452357.2 IDL> Print, values 1.57100 -8.41400 -4.89800
While the calendar data format seems complicated, it is actually quite straightforward. Like other data formats, it is a string enclosed in parentheses, and then all calendar subformats are enclosed inside the parentheses of a C() statement. See the example below. In this format, the "3G0" is a format specifier for the floating point values in the file and appear outside the C() statement. The "x" values in the C() statement are the normal space values found in format statements and can appear with multipliers if required by the data (e.g., "3x").
timeformat = '(C(CDI,x,CMOI,x,CYI,x,CHI,x,CMI,x,CSF,x),3G0)'
The calendar subformats also appear complicated, but are simple to understand, too. Each calendar subformat starts with a "C", then comes some kind of calendar unit, such as a month (MO), day (D), year (Y), minute (M), and so on, followed by the type of data that will be transfered: I (integer), A (string), or F (floating point). So, for example, if you are going to read a month value out of a file, and the month is stored in the file as an integer, the subformat will be "CMOI". If you want to write the month out as a string, you will use the format "CMOA". In this case, the month will be uppercase (because you used uppercase characters (i.e., "MO") to specify the month. If only the first letter of the month should be capitalized, you would use "Mo" to describe the month (i.e., "CMoA"), or is you want the month in all lowercase letters, the month would be specified with lowercase letters, "CmoA"
IDL> Print, time, Format='(C(CMOA))' MAR IDL> Print, time, Format='(C(CMoA))' Mar IDL> Print, time, Format='(C(CmoA))' mar
Suppose you wish to write the time out in a calendar date format. You might do this.
IDL> dateFormat = '(C(CDwA, X, CMoA, X, CDI, X, CHI2.2, ":", CMI2.2, ":", CSI2.2, X, CYI4))' IDL> Print, time, Format=dateFormat Sat Mar 23 16:11:33 2002
In your case, if you wanted to read your data file and print the dates out, you might write code like this.
; Open the file and read the data into a string array. filename = 'time_test.txt' nrows = File_Lines(filename) OpenR, lun, filename, /Get_Lun data = StrArr(nrows) ReadF, lun, data Free_Lun, lun ; Read each row of data and output just the date in calendar format. time = 0D values = fltarr(3) inputFormat = '(C(CDI,x,CMOI,x,CYI,x,CHI,x,CMI,x,CSF,x),3g0)' outputFormat = '(C(CDwA, X, CMoA, X, CDI, X, CHI2.2, ":", CMI2.2, ":", CSI2.2, X, CYI4))' FOR j=0,nrows-1 DO BEGIN ReadS,data[j], time, values, Format=inputFormat Print, time, Format=outputFormat ENDFOR END
Run the program like this.
IDL> .Run time_test Sat Mar 23 16:11:33 2002 Sat Mar 23 16:11:49 2002 Sat Mar 23 16:12:05 2002 Sat Mar 23 16:12:21 2002
Version of IDL used to prepare this article: IDL 8.2.3.