Go to the first, previous, next, last section, table of contents.


A user-friendlier way to parse times and dates

The Unix standard defines another function to parse date strings. The interface is, mildly said, weird. But if this function fits into the application to be written it is just fine. It is a problem when using this function in multi-threaded programs or in libraries since it returns a pointer to a static variable, uses a global variable, and a global state (an environment variable).

Variable: getdate_err
This variable of type int will contain the error code of the last unsuccessful call of the getdate function. Defined values are:

@math{1}
The environment variable DATEMSK is not defined or null.
@math{2}
The template file denoted by the DATEMSK environment variable cannot be opened.
@math{3}
Information about the template file cannot retrieved.
@math{4}
The template file is no regular file.
@math{5}
An I/O error occurred while reading the template file.
@math{6}
Not enough memory available to execute the function.
@math{7}
The template file contains no matching template.
@math{8}
The input string is invalid for a template which would match otherwise. This includes error like February 31st, or return values which can be represented using time_t.

Function: struct tm * getdate (const char *string)
The interface of the getdate function is the simplest possible for a function to parse a string and return the value. string is the input string and the result is passed to the user in a statically allocated variable.

The details about how the string is processed is hidden from the user. In fact, it can be outside the control of the program. Which formats are recognized is controlled by the file named by the environment variable DATEMSK. The content of the named file should contain lines of valid format strings which could be passed to strptime.

The getdate function reads these format strings one after the other and tries to match the input string. The first line which completely matches the input string is used.

Elements which were not initialized through the format string get assigned the values of the time the getdate function is called.

The format elements recognized by getdate are the same as for strptime. See above for an explanation. There are only a few extension to the strptime behavior:

It should be noted that the format in the template file need not only contain format elements. The following is a list of possible format strings (taken from the Unix standard):

%m
%A %B %d, %Y %H:%M:%S
%A
%B
%m/%d/%y %I %p
%d,%m,%Y %H:%M
at %A the %dst of %B in %Y
run job at %I %p,%B %dnd
%A den %d. %B %Y %H.%M Uhr

As one can see the template list can contain very specific strings like run job at %I %p,%B %dnd. Using the above list of templates and assuming the current time is Mon Sep 22 12:19:47 EDT 1986 we can get the following results for the given input.

@multitable {xxxxxxxxxxxx} {xxxxxxxxxx} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}

  • Mon @tab %a @tab Mon Sep 22 12:19:47 EDT 1986
  • Sun @tab %a @tab Sun Sep 28 12:19:47 EDT 1986
  • Fri @tab %a @tab Fri Sep 26 12:19:47 EDT 1986
  • September @tab %B @tab Mon Sep 1 12:19:47 EDT 1986
  • January @tab %B @tab Thu Jan 1 12:19:47 EST 1987
  • December @tab %B @tab Mon Dec 1 12:19:47 EST 1986
  • Sep Mon @tab %b %a @tab Mon Sep 1 12:19:47 EDT 1986
  • Jan Fri @tab %b %a @tab Fri Jan 2 12:19:47 EST 1987
  • Dec Mon @tab %b %a @tab Mon Dec 1 12:19:47 EST 1986
  • Jan Wed 1989 @tab %b %a %Y @tab Wed Jan 4 12:19:47 EST 1989
  • Fri 9 @tab %a %H @tab Fri Sep 26 09:00:00 EDT 1986
  • Feb 10:30 @tab %b %H:%S @tab Sun Feb 1 10:00:30 EST 1987
  • 10:30 @tab %H:%M @tab Tue Sep 23 10:30:00 EDT 1986
  • 13:30 @tab %H:%M @tab Mon Sep 22 13:30:00 EDT 1986 The return value of the function is a pointer to a static variable of type struct tm or a null pointer if an error occurred. The result in the variable pointed to by the return value is only valid until the next getdate call which makes this function unusable in multi-threaded applications. The errno variable is not changed. Error conditions are signalled using the global variable getdate_err. See the description above for a list of the possible error values. Warning: The getdate function should never be used in SUID-programs. The reason is obvious: using the DATEMSK environment variable one can get the function to open any arbitrary file and chances are high that with some bogus input (such as a binary file) the program will crash.
  • Function: int getdate_r (const char *string, struct tm *tp)
    The getdate_r function is the reentrant counterpart of getdate. It does not use the global variable getdate_err to signal the error but instead the return value now is this error code. The same error codes as described in the getdate_err documentation above are used. getdate_r also does not store the broken-down time in a static variable. Instead it takes an second argument which must be a pointer to a variable of type struct tm where the broken-down can be stored. This function is not defined in the Unix standard. Nevertheless it is available on some other Unix systems as well. As for getdate the warning for using this function in SUID-programs applies to getdate_r as well.


    Go to the first, previous, next, last section, table of contents.