> I often miss an at-least-pseudo-standard means of converting a
> reasonable string date/time specification into a "struct tm", and,
> from the number of requests on different newsgroups, it appears
> others do too. Perhaps adding one to the "tz" package might be
> a reasonable thing to do?
My first attempt at coming up with such a routine was "strptime()", in
SunOS 4.1[.x]. It's somewhat of a "strftime()" inverse; it takes a
format string and a date/time string, and fills in a "struct tm".
Good things about it:
it returns a pointer one past the last character processed, so
you can continue sucking other stuff out of the string.
fairly easy to internationalize, *if* your locale-support system
lets you ask for various date formats for the current locale
(SunOS 4.1[.x]'s does; not all others do).
Bad things about it:
the way it supports "optional" fields - e.g., leaving the
seconds or minutes out and getting 0, or leaving the year
out and getting this year, is a gross hack - "strptime()"
"knows" that those fields are optional.
Steve Bellovin came up with a rather powerful function, "getdate()",
which appears in the B news source, among other places. It has a YACC
grammar to parse the string, and can handle all sorts of special
strings, such as "tomorrow", "now", "next week", etc.. It takes a
pointer to the string to be scanned, and a pointer to a "struct timeb"
containing the current time, as arguments, and returns a "time_t".
Good things about it:
takes a *very* large number of different specifications and
turns them into dates.
Bad things about it:
it's hard to "internationalize", because the grammar is hardcoded, as
are the actions for different reductions; the best way to
internationalize it would probably be to hand-code different
versions for different locales, and have the common "getdate()"
routine load up the appropriate version, based on the setting of
the LANG environment variable, at run time. Not all systems
have run-time dynamic loading as a standard feature.
it should really split the "string to 'struct tm'" and "'struct tm'
to 'time_t'" functions up - i.e., just make it convert a string
to a "struct tm", and let "mktime()" to the rest.
it doesn't return a pointer one past the last character processed.
System V Release 4 also has a routine named "getdate()", but it's
different. It takes a string as an argument, and returns a pointer to a
"struct tm". It works by getting a list of "strftime()"-style date
formats from a file, and scanning the string against each of them; if it
finds one that matches, it returns a "struct tm" based on that match.
Good things about it:
it can deal with optional fields, and doesn't have "strptime()"s
gross hack to do it; you just have multiple formats, some with
the optional fields, and some without.
Bad things about it:
it's not clear it responds to the setting of LANG, so
localization isn't as good as it could be.
it doesn't return a pointer one past the last character processed.
My personal preferences are, in order:
a Bellovin-style "getdate()", with the modifications I suggest;
if all systems had run-time dynamic loading, I think that'd be
ideal.
an SVR4-style "getdate()", with the list of strings selected by
the setting of LANG.