[Gnucash-changes] fix the documentation surrounding the
gnc_iso8601_to_timespec routine().
Linas Vepstas
linas at cvs.gnucash.org
Sun May 2 18:04:07 EDT 2004
Log Message:
-----------
fix the documentation surrounding the gnc_iso8601_to_timespec routine().
Modified Files:
--------------
gnucash/src/engine:
gnc-date.c
gnc-date.h
Revision Data
-------------
Index: gnc-date.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-date.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -Lsrc/engine/gnc-date.h -Lsrc/engine/gnc-date.h -u -r1.8 -r1.9
--- src/engine/gnc-date.h
+++ src/engine/gnc-date.h
@@ -34,7 +34,22 @@
applications, besides just GnuCash, use this file. In particular,
GnoTime (gttr.sourcefore.net) uses this file, and this file is
formally a part of QOF (qof.sourceforge.net).
- *
+
+ An important note about time-keeping: The general goal of any
+ program that works with numeric time values SHOULD BE to always
+ stores and use UNIVERSAL TIME internally. Universal time is the
+ 'one true time' that is independent of one's location on planet
+ Earth. It is measured in seconds from midnight January 1, 1970
+ in localtime-Grenwich (GMT). If one wants to display the local
+ time, then the display-print routine should make all final
+ tweaks to print the local time. The local time *must not* be
+ kept as a numeric value anywhere in the program. If one wants
+ to parse a user's input string as if it were local time, then
+ the output of the parse routine MUST BE universal time.
+ A sane program must never ever store (to file or db) a time
+ that is not Universal Time. Break these rules, and you will
+ rue the day...
+
@author Copyright (C) 1997 Robin D. Clark <rclark at cs.hmc.edu>
@author Copyright (C) 1998-2001,2003 Linas Vepstas <linas at linas.org>
*/
@@ -173,25 +188,40 @@
/** Same as gnc_dmy2timespec, but last second of the day */
Timespec gnc_dmy2timespec_end (int day, int month, int year);
-/** The gnc_iso8601_to_timespec_local() routine converts an ISO-8601 style
- * date/time string to Timespec.
- * For example: 1998-07-17 11:00:00.68-05
- * is 680 milliseconds after 11 o'clock, central daylight time
- * \return The time in local time.*/
-Timespec gnc_iso8601_to_timespec_local(const char *);
-
/** The gnc_iso8601_to_timespec_gmt() routine converts an ISO-8601 style
- * date/time string to Timespec.
- * For example: 1998-07-17 11:00:00.68-05
+ * date/time string to Timespec. Please note that ISO-8601 strings
+ * are a representation of Universal Time (UTC), and as such, they
+ * 'store' UTC. To make them human readable, they show timezone
+ * information along with a local-time string. But fundamentally,
+ * they *are* UTC. Thus, thir routine takes a UTC input, and
+ * returns a UTC output.
+ *
+ * For example: 1998-07-17 11:00:00.68-0500
* is 680 milliseconds after 11 o'clock, central daylight time
- * \return The time in gmt. */
+ * It is also 680 millisecs after 16:00:00 hours UTC.
+ * \return The universl time.
+ *
+ * XXX Caution: this routine does not handle strings that specify
+ * times before January 1 1970.
+ */
Timespec gnc_iso8601_to_timespec_gmt(const char *);
-/** The gnc_timespec_to_iso8601_buff() routine prints a Timespec
-* as an ISO-8601 style string. The buffer must be long enough
-* to contain the NULL-terminated string (32 characters + NUL). This
-* routine returns a pointer to the null terminator (and can
-* thus be used in the 'stpcpy' metaphor of string concatenation).*/
+/** The gnc_timespec_to_iso8601_buff() routine takes the input
+ * UTC Timespec value and prints it as an ISO-8601 style string.
+ * The buffer must be long enough to contain the NULL-terminated
+ * string (32 characters + NUL). This routine returns a pointer
+ * to the null terminator (and can thus be used in the 'stpcpy'
+ * metaphor of string concatenation).
+ *
+ * Please note that ISO-8601 strings are a representation of
+ * Universal Time (UTC), and as such, they 'store' UTC. To make them
+ * human readable, they show timezone information along with a
+ * local-time string. But fundamentally, they *are* UTC. Thus,
+ * this routine takes a UTC input, and returns a UTC output.
+ *
+ * The string generated by this routine uses the local timezone
+ * on the machine on which it is executing to create the timestring.
+ */
char * gnc_timespec_to_iso8601_buff (Timespec ts, char * buff);
/** DOCUMENT ME! FIXME: Probably similar to xaccDMYToSec() this date
@@ -206,7 +236,12 @@
/** \warning hack alert XXX FIXME -- these date routines return incorrect
* values for dates before 1970. Most of them are good only up
- * till 2038. This needs fixing ... */
+ * till 2038. This needs fixing ...
+ *
+ * XXX This routine should be modified to assume that the
+ * the user wanted the time at noon, localtime. The returned
+ * time_t should be seconds (at GMT) of the local noon-time.
+*/
time_t xaccDMYToSec (int day, int month, int year);
/** The gnc_timezone function returns the number of seconds *west*
Index: gnc-date.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-date.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -Lsrc/engine/gnc-date.c -Lsrc/engine/gnc-date.c -u -r1.8 -r1.9
--- src/engine/gnc-date.c
+++ src/engine/gnc-date.c
@@ -962,8 +962,8 @@
/* hack alert -- this routine returns incorrect values for
* dates before 1970 */
-static Timespec
-gnc_iso8601_to_timespec(const char *str, int do_localtime)
+Timespec
+gnc_iso8601_to_timespec_gmt(const char *str)
{
char buf[4];
Timespec ts;
@@ -987,7 +987,7 @@
str = strchr (str, ':'); if (str) { str++; } else { return ts; }
stm.tm_sec = atoi (str);
- /* the decimal point, optionally present ... */
+ /* The decimal point, optionally present ... */
/* hack alert -- this algo breaks if more than 9 decimal places present */
if (strchr (str, '.'))
{
@@ -999,7 +999,7 @@
}
stm.tm_isdst = -1;
- /* timezone format can be +hh or +hhmm or +hh.mm (or -) (or not present) */
+ /* Timezone format can be +hh or +hhmm or +hh.mm (or -) (or not present) */
str += strcspn (str, "+-");
if (str)
{
@@ -1024,8 +1024,12 @@
}
}
- /* adjust for the local timezone */
- if (do_localtime)
+ /* Note that mktime returns 'local seconds' which is the true time
+ * minus the timezone offset. We don't want to work with local
+ * seconds, since they swim around acording to daylight savings, etc.
+ * We want to work with universal time. Thus, add an offset
+ * to undo the damage that mktime causes.
+ */
{
struct tm tmp_tm;
struct tm *tm;
@@ -1054,25 +1058,12 @@
stm.tm_isdst = tmp_tm.tm_isdst;
}
- /* compute number of seconds */
ts.tv_sec = mktime (&stm);
ts.tv_nsec = nsec;
return ts;
}
-Timespec
-gnc_iso8601_to_timespec_local(const char *str)
-{
- return gnc_iso8601_to_timespec(str, 1);
-}
-
-Timespec
-gnc_iso8601_to_timespec_gmt(const char *str)
-{
- return gnc_iso8601_to_timespec(str, 0);
-}
-
/********************************************************************\
\********************************************************************/
@@ -1093,8 +1084,8 @@
if (0>tz_min) { tz_min +=60; tz_hour --; }
if (60<=tz_min) { tz_min -=60; tz_hour ++; }
- /* we also have to print the sign by hand, to work around a bug
- * in the glibc 2.1.3 printf (where %+02d fails to zero-pad)
+ /* We also have to print the sign by hand, to work around a bug
+ * in the glibc 2.1.3 printf (where %+02d fails to zero-pad).
*/
cyn = '-';
if (0>tz_hour) { cyn = '+'; tz_hour = -tz_hour; }
@@ -1111,7 +1102,7 @@
tz_hour,
tz_min);
- /* return pointer to end of string */
+ /* Return pointer to end of string. */
buff += len;
return buff;
}
More information about the Gnucash-changes
mailing list