Date: Date and Time Printing, Parsing and Manipulation
[Query Object Framework]


Detailed Description

Utility functions to handle date and time (adjusting, getting the current date, printing the date and time, etc.)

Overall, this file is quite a mess. Note, however, that other 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...

Warning:
HACK ALERT -- the scan and print routines should probably be moved to somewhere else. The engine really isn't involved with things like printing formats. This is needed mostly by the GUI and so on. If a file-io backend needs date handling, it should do it itself, instead of depending on the routines here.
(to be renamed qofdate.h in libqof2.)

Author:
Copyright (C) 1997 Robin D. Clark <rclark@cs.hmc.edu>

Copyright (C) 1998-2001,2003 Linas Vepstas <linas@linas.org>


Files

file  gnc-date.h
 Date and Time handling routines.

Data Structures

struct  timespec64
 Use a 64-bit signed int timespec. More...

String / DateFormat conversion.

const char * gnc_date_dateformat_to_string (QofDateFormat format)
 The string->value versions return FALSE on success and TRUE on failure.
gboolean gnc_date_string_to_dateformat (const char *format_string, QofDateFormat *format)
 Converts the date format to a printable string.
const char * gnc_date_monthformat_to_string (GNCDateMonthFormat format)
gboolean gnc_date_string_to_monthformat (const char *format_string, GNCDateMonthFormat *format)
 Converts the month format to a printable string.

Timespec functions

gboolean timespec_equal (const Timespec *ta, const Timespec *tb)
int timespec_cmp (const Timespec *ta, const Timespec *tb)
Timespec timespec_diff (const Timespec *ta, const Timespec *tb)
Timespec timespec_abs (const Timespec *t)
Timespec timespecCanonicalDayTime (Timespec t)
void timespecFromTime_t (Timespec *ts, time_t t)
time_t timespecToTime_t (Timespec ts)
Timespec gnc_dmy2timespec (int day, int month, int year)
Timespec gnc_dmy2timespec_end (int day, int month, int year)
Timespec gnc_iso8601_to_timespec_gmt (const char *)
char * gnc_timespec_to_iso8601_buff (Timespec ts, char *buff)
void gnc_timespec2dmy (Timespec ts, int *day, int *month, int *year)
void date_add_months (struct tm *tm, int months, gboolean track_last_day)
time_t xaccDMYToSec (int day, int month, int year)
long int gnc_timezone (struct tm *tm)

QofDateFormat functions

QofDateFormat qof_date_format_get (void)
void qof_date_format_set (QofDateFormat df)
const gchar * qof_date_format_get_string (QofDateFormat df)
const gchar * qof_date_text_format_get_string (QofDateFormat df)

Date Printing/Scanning functions

size_t qof_print_date_dmy_buff (char *buff, size_t buflen, int day, int month, int year)
size_t qof_print_date_buff (char *buff, size_t buflen, time_t secs)
size_t qof_print_gdate (char *buf, size_t bufflen, GDate *gd)
char * qof_print_date (time_t secs)
const char * gnc_print_date (Timespec ts)
size_t qof_print_hours_elapsed_buff (char *buff, size_t len, int secs, gboolean show_secs)
size_t qof_print_minutes_elapsed_buff (char *buff, size_t len, int secs, gboolean show_secs)
size_t qof_print_time_buff (char *buff, size_t len, time_t secs)
size_t qof_print_date_time_buff (char *buff, size_t len, time_t secs)
gboolean qof_is_same_day (time_t, time_t)
char * xaccDateUtilGetStamp (time_t thyme)
gboolean qof_scan_date (const char *buff, int *day, int *month, int *year)
gboolean qof_scan_date_secs (const char *buff, time_t *secs)

Date Start/End Adjustment routines

Given a time value, adjust it to be the beginning or end of that day.

static void gnc_tm_set_day_start (struct tm *tm)
static void gnc_tm_set_day_middle (struct tm *tm)
static void gnc_tm_set_day_end (struct tm *tm)
void gnc_tm_get_day_start (struct tm *tm, time_t time_val)
void gnc_tm_get_day_end (struct tm *tm, time_t time_val)
time_t gnc_timet_get_day_start (time_t time_val)
time_t gnc_timet_get_day_end (time_t time_val)
time_t gnc_timet_get_day_start_gdate (GDate *date)
time_t gnc_timet_get_day_end_gdate (GDate *date)
int date_get_last_mday (struct tm *tm)
gboolean date_is_last_mday (struct tm *tm)
int gnc_date_my_last_mday (int month, int year)
int gnc_timespec_last_mday (Timespec ts)

Today's Date

void gnc_tm_get_today_start (struct tm *tm)
void gnc_tm_get_today_end (struct tm *tm)
time_t gnc_timet_get_today_start (void)
time_t gnc_timet_get_today_end (void)
char * xaccDateUtilGetStampNow (void)

Defines

#define MAX_DATE_LENGTH   31
#define QOF_UTC_DATE_FORMAT   "%Y-%m-%dT%H:%M:%SZ"
 UTC date format string.
#define DATE_FORMAT_FIRST   QOF_DATE_FORMAT_US
#define DATE_FORMAT_LAST   QOF_DATE_FORMAT_LOCALE
#define qof_date_format_get_format   qof_date_text_format_get_string

Typedefs

typedef timespec64 Timespec

Enumerations

enum  QofDateFormat {
  QOF_DATE_FORMAT_US, QOF_DATE_FORMAT_UK, QOF_DATE_FORMAT_CE, QOF_DATE_FORMAT_ISO,
  QOF_DATE_FORMAT_UTC, QOF_DATE_FORMAT_LOCALE, QOF_DATE_FORMAT_CUSTOM
}
enum  GNCDateMonthFormat { GNCDATE_MONTH_NUMBER, GNCDATE_MONTH_ABBREV, GNCDATE_MONTH_NAME }

Functions

char dateSeparator (void)


Define Documentation

#define MAX_DATE_LENGTH   31
 

The maximum length of a string created by the date printers

Definition at line 67 of file gnc-date.h.

#define qof_date_format_get_format   qof_date_text_format_get_string
 

Deprecated:
qof_date_format_get_format has been replaced by qof_date_text_format_get_string

Definition at line 98 of file gnc-date.h.

#define QOF_UTC_DATE_FORMAT   "%Y-%m-%dT%H:%M:%SZ"
 

UTC date format string.

Timezone independent, date and time inclusive, as used in the QSF backend. The T and Z characters are from xsd:dateTime format in coordinated universal time, UTC. You can reproduce the string from the GNU/Linux command line using the date utility: date -u +Y-m-dTH:M:SZ = 2004-12-12T23:39:11Z The datestring must be timezone independent and include all specified fields. Remember to use gmtime() NOT localtime()!

Definition at line 79 of file gnc-date.h.


Typedef Documentation

typedef struct timespec64 Timespec
 

The Timespec is just like the unix 'struct timespec' except that we use a 64-bit signed int to store the seconds. This should adequately cover dates in the distant future as well as the distant past, as long as they're not more than a couple dozen times the age of the universe. Note that both gcc and the IBM Toronto xlC compiler (aka CSet, VisualAge, etc) correctly handle long long as a 64 bit quantity, even on the 32-bit Intel x86 and PowerPC architectures. I'm assuming that all the other modern compilers are clean on this issue too.

Definition at line 168 of file gnc-date.h.


Enumeration Type Documentation

enum GNCDateMonthFormat
 

This is how to format the month, as a number, an abbreviated string, or the full name.

Definition at line 104 of file gnc-date.h.

00104              {
00105   GNCDATE_MONTH_NUMBER,
00106   GNCDATE_MONTH_ABBREV,
00107   GNCDATE_MONTH_NAME
00108 } GNCDateMonthFormat;

enum QofDateFormat
 

Enum for determining a date format

Enumerator:
QOF_DATE_FORMAT_US  United states: mm/dd/yyyy
QOF_DATE_FORMAT_UK  Britain: dd/mm/yyyy
QOF_DATE_FORMAT_CE  Continental Europe: dd.mm.yyyy
QOF_DATE_FORMAT_ISO  ISO: yyyy-mm-dd
QOF_DATE_FORMAT_UTC  UTC: 2004-12-12T23:39:11Z
QOF_DATE_FORMAT_LOCALE  Take from locale information
QOF_DATE_FORMAT_CUSTOM  Used by the check printing code

Definition at line 82 of file gnc-date.h.


Function Documentation

void date_add_months struct tm *  tm,
int  months,
gboolean  track_last_day
 

Add a number of months to a time value and normalize. Optionally also track the last day of the month, i.e. 1/31 -> 2/28 -> 3/30.

Definition at line 311 of file gnc-date.c.

00312 {
00313   gboolean was_last_day;
00314   int new_last_mday;
00315 
00316   /* Have to do this now */
00317   was_last_day = date_is_last_mday(tm);
00318 
00319   /* Add in the months and normalize */
00320   tm->tm_mon += months;
00321   while (tm->tm_mon > 11) {
00322     tm->tm_mon -= 12;
00323     tm->tm_year++;
00324   }
00325 
00326   if (!track_last_day)
00327     return;
00328 
00329   /* Track last day of the month, i.e. 1/31 -> 2/28 -> 3/30 */
00330   new_last_mday = date_get_last_mday(tm);
00331   if (was_last_day || (tm->tm_mday > new_last_mday))
00332     tm->tm_mday = new_last_mday;
00333 }

int date_get_last_mday struct tm *  tm  ) 
 

Get the numerical last date of the month. (28, 29, 30, 31)

Definition at line 283 of file gnc-date.c.

00284 {
00285   return gnc_date_my_last_mday (tm->tm_mon+1, tm->tm_year+1900);
00286 }

gboolean date_is_last_mday struct tm *  tm  ) 
 

Is the mday field the last day of the specified month.

Definition at line 295 of file gnc-date.c.

00296 {
00297   return(tm->tm_mday == date_get_last_mday(tm));
00298 }

char dateSeparator void   ) 
 

dateSeparator Return the field separator for the current date format

Args: none

Return: date character

Globals: global dateFormat value

Definition at line 920 of file gnc-date.c.

00921 {
00922   static char locale_separator = '\0';
00923 
00924   switch (dateFormat)
00925   {
00926     case QOF_DATE_FORMAT_CE:
00927       return '.';
00928     case QOF_DATE_FORMAT_ISO:
00929     case QOF_DATE_FORMAT_UTC:
00930       return '-';
00931     case QOF_DATE_FORMAT_US:
00932     case QOF_DATE_FORMAT_UK:
00933     default:
00934       return '/';
00935     case QOF_DATE_FORMAT_LOCALE:
00936       if (locale_separator != '\0')
00937         return locale_separator;
00938       else
00939       { /* Make a guess */
00940         char string[256];
00941         struct tm *tm;
00942         time_t secs;
00943         char *s;
00944 
00945         secs = time(NULL);
00946         tm = localtime(&secs);
00947         strftime(string, sizeof(string), GNC_D_FMT, tm);
00948 
00949         for (s = string; s != '\0'; s++)
00950           if (!isdigit(*s))
00951             return (locale_separator = *s);
00952       }
00953   }
00954 
00955   return '\0';
00956 }

int gnc_date_my_last_mday int  month,
int  year
 

DOCUMENT ME! Probably the same as date_get_last_mday()

Definition at line 257 of file gnc-date.c.

00258 {
00259   gboolean is_leap;
00260   static int days_in_month[2][12] =
00261     {/* non leap */ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
00262      /*   leap   */ {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
00263 
00264   /* Is this a leap year? */
00265   if (year % 2000 == 0)
00266     is_leap = TRUE;
00267   else if (year % 400 == 0)
00268       is_leap = FALSE;
00269   else
00270     is_leap = (year % 4 == 0);
00271 
00272   return days_in_month[is_leap][month-1];
00273 }

gboolean gnc_date_string_to_dateformat const char *  format_string,
QofDateFormat format
 

Converts the date format to a printable string.

Note the reversed return values!

Returns:
FALSE on success, TRUE on failure.

Definition at line 101 of file gnc-date.c.

00102 {
00103   if (!fmt_str)
00104     return TRUE;
00105 
00106   if (!strcmp(fmt_str, "us"))
00107     *format = QOF_DATE_FORMAT_US;
00108   else if (!strcmp(fmt_str, "uk"))
00109     *format = QOF_DATE_FORMAT_UK;
00110   else if (!strcmp(fmt_str, "ce"))
00111     *format = QOF_DATE_FORMAT_CE;
00112   else if (!strcmp(fmt_str, "utc"))
00113     *format = QOF_DATE_FORMAT_UTC;
00114   else if (!strcmp(fmt_str, "iso"))
00115     *format = QOF_DATE_FORMAT_ISO;
00116   else if (!strcmp(fmt_str, "locale"))
00117     *format = QOF_DATE_FORMAT_LOCALE;
00118   else if (!strcmp(fmt_str, "custom"))
00119     *format = QOF_DATE_FORMAT_CUSTOM;
00120   else
00121     return TRUE;
00122 
00123   return FALSE;
00124 }

gboolean gnc_date_string_to_monthformat const char *  format_string,
GNCDateMonthFormat format
 

Converts the month format to a printable string.

Note the reversed return values!

Returns:
FALSE on success, TRUE on failure.

Definition at line 143 of file gnc-date.c.

00144 {
00145   if (!fmt_str)
00146     return TRUE;
00147 
00148   if (!strcmp(fmt_str, "number"))
00149     *format = GNCDATE_MONTH_NUMBER;
00150   else if (!strcmp(fmt_str, "abbrev"))
00151     *format = GNCDATE_MONTH_ABBREV;
00152   else if (!strcmp(fmt_str, "name"))
00153     *format = GNCDATE_MONTH_NAME;
00154   else
00155     return TRUE;
00156 
00157   return FALSE;
00158 }

Timespec gnc_dmy2timespec int  day,
int  month,
int  year
 

Convert a day, month, and year to a Timespec

Definition at line 1243 of file gnc-date.c.

01244 {
01245   return gnc_dmy2timespec_internal (day, month, year, TRUE);
01246 }

Timespec gnc_dmy2timespec_end int  day,
int  month,
int  year
 

Same as gnc_dmy2timespec, but last second of the day

Definition at line 1249 of file gnc-date.c.

01250 {
01251   return gnc_dmy2timespec_internal (day, month, year, FALSE);
01252 }

Timespec gnc_iso8601_to_timespec_gmt const char *   ) 
 

The gnc_iso8601_to_timespec_gmt() routine converts an ISO-8601 style 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 It is also 680 millisecs after 16:00:00 hours UTC.

Returns:
The universl time.
XXX Caution: this routine does not handle strings that specify times before January 1 1970.

Definition at line 1012 of file gnc-date.c.

01013 {
01014   char buf[4];
01015   Timespec ts;
01016   struct tm stm;
01017   long int nsec =0;
01018 
01019   ts.tv_sec=0;
01020   ts.tv_nsec=0;
01021   if (!str) return ts;
01022 
01023   stm.tm_year = atoi(str) - 1900;
01024   str = strchr (str, '-'); if (str) { str++; } else { return ts; }
01025   stm.tm_mon = atoi(str) - 1;
01026   str = strchr (str, '-'); if (str) { str++; } else { return ts; }
01027   stm.tm_mday = atoi(str);
01028 
01029   str = strchr (str, ' '); if (str) { str++; } else { return ts; }
01030   stm.tm_hour = atoi(str);
01031   str = strchr (str, ':'); if (str) { str++; } else { return ts; }
01032   stm.tm_min = atoi(str);
01033   str = strchr (str, ':'); if (str) { str++; } else { return ts; }
01034   stm.tm_sec = atoi (str);
01035 
01036   /* The decimal point, optionally present ... */
01037   /* hack alert -- this algo breaks if more than 9 decimal places present */
01038   if (strchr (str, '.')) 
01039   { 
01040      int decimals, i, multiplier=1000000000;
01041      str = strchr (str, '.') +1;
01042      decimals = strcspn (str, "+- ");
01043      for (i=0; i<decimals; i++) multiplier /= 10;
01044      nsec = atoi(str) * multiplier;
01045   }
01046   stm.tm_isdst = -1;
01047 
01048   /* Timezone format can be +hh or +hhmm or +hh.mm (or -) (or not present) */
01049   str += strcspn (str, "+-");
01050   if (str)
01051   {
01052     buf[0] = str[0];
01053     buf[1] = str[1];
01054     buf[2] = str[2];
01055     buf[3] = 0;
01056     stm.tm_hour -= atoi(buf);
01057 
01058     str +=3;
01059     if ('.' == *str) str++;
01060     if (isdigit (*str) && isdigit (*(str+1)))
01061     {
01062       int cyn;
01063       /* copy sign from hour part */
01064       if ('+' == buf[0]) { cyn = -1; } else { cyn = +1; } 
01065       buf[0] = str[0];
01066       buf[1] = str[1];
01067       buf[2] = str[2];
01068       buf[3] = 0;
01069       stm.tm_min += cyn * atoi(buf);
01070     }
01071   }
01072 
01073   /* Note that mktime returns 'local seconds' which is the true time
01074    * minus the timezone offset.  We don't want to work with local 
01075    * seconds, since they swim around acording to daylight savings, etc. 
01076    * We want to work with universal time.  Thus, add an offset
01077    * to undo the damage that mktime causes.
01078    */
01079   {
01080     struct tm tmp_tm;
01081     struct tm *tm;
01082     long int tz;
01083     int tz_hour;
01084     time_t secs;
01085 
01086     /* Use a temporary tm struct so the mktime call below
01087      * doesn't mess up stm. */
01088     tmp_tm = stm;
01089     tmp_tm.tm_isdst = -1;
01090 
01091     secs = mktime (&tmp_tm);
01092 
01093     /* The call to localtime is 'bogus', but it forces 'timezone' to
01094      * be set. Note that we must use the accurate date, since the
01095      * value of 'gnc_timezone' includes daylight savings corrections
01096      * for that date. */
01097     tm = localtime (&secs);
01098 
01099     tz = gnc_timezone (tm);
01100 
01101     tz_hour = tz / 3600;
01102     stm.tm_hour -= tz_hour;
01103     stm.tm_min -= (tz - (3600 * tz_hour)) / 60;
01104     stm.tm_isdst = tmp_tm.tm_isdst;
01105   }
01106 
01107   ts.tv_sec = mktime (&stm);
01108   ts.tv_nsec = nsec;
01109 
01110   return ts;
01111 }

const char* gnc_print_date Timespec  ts  ) 
 

Convenience; calls through to qof_print_date_dmy_buff(). Return: static global string.

Warning:
This routine is not thread-safe, because it uses a single global buffer to store the return value. Use qof_print_date_buff() or qof_print_date() instead.

Definition at line 528 of file gnc-date.c.

00529 {
00530   static char buff[MAX_DATE_LENGTH];
00531   time_t t;
00532 
00533   t = ts.tv_sec + (ts.tv_nsec / 1000000000.0);
00534 
00535   qof_print_date_buff (buff, MAX_DATE_LENGTH, t);
00536 
00537   return buff;
00538 }

void gnc_timespec2dmy Timespec  ts,
int *  day,
int *  month,
int *  year
 

DOCUMENT ME! FIXME: Probably similar to xaccDMYToSec() this date routine might return incorrect values for dates before 1970.

Definition at line 1166 of file gnc-date.c.

01167 {
01168   struct tm *result;
01169   time_t t_secs = t.tv_sec + (t.tv_nsec / NANOS_PER_SECOND);
01170   result = localtime(&t_secs);
01171 
01172   if (day) *day = result->tm_mday;
01173   if (month) *month = result->tm_mon+1;
01174   if (year) *year = result->tm_year+1900;
01175 }

int gnc_timespec_last_mday Timespec  ts  ) 
 

DOCUMENT ME! Probably the same as date_get_last_mday()

Definition at line 1157 of file gnc-date.c.

01158 {
01159   struct tm *result;
01160   time_t t_secs = t.tv_sec + (t.tv_nsec / NANOS_PER_SECOND);
01161   result = localtime(&t_secs);
01162   return date_get_last_mday (result);
01163 }

char* gnc_timespec_to_iso8601_buff Timespec  ts,
char *  buff
 

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.

Definition at line 1117 of file gnc-date.c.

01118 {
01119   int len;
01120   int tz_hour, tz_min;
01121   char cyn;
01122   time_t tmp;
01123   struct tm parsed;
01124 
01125   tmp = ts.tv_sec;
01126   localtime_r(&tmp, &parsed);
01127 
01128   tz_hour = gnc_timezone (&parsed) / 3600;
01129   tz_min = (gnc_timezone (&parsed) - 3600*tz_hour) / 60;
01130   if (0>tz_min) { tz_min +=60; tz_hour --; }
01131   if (60<=tz_min) { tz_min -=60; tz_hour ++; }
01132 
01133   /* We also have to print the sign by hand, to work around a bug
01134    * in the glibc 2.1.3 printf (where %+02d fails to zero-pad).
01135    */
01136   cyn = '-';
01137   if (0>tz_hour) { cyn = '+'; tz_hour = -tz_hour; }
01138 
01139   len = sprintf (buff, "%4d-%02d-%02d %02d:%02d:%02d.%06ld %c%02d%02d",
01140                  parsed.tm_year + 1900,
01141                  parsed.tm_mon + 1,
01142                  parsed.tm_mday,
01143                  parsed.tm_hour,
01144                  parsed.tm_min,
01145                  parsed.tm_sec,
01146                  ts.tv_nsec / 1000,
01147                  cyn,
01148                  tz_hour,
01149                  tz_min);
01150 
01151   /* Return pointer to end of string. */
01152   buff += len;
01153   return buff;
01154 }

time_t gnc_timet_get_day_end time_t  time_val  ) 
 

The gnc_timet_get_day_end() routine will take the given time in seconds and adjust it to the last second of that day.

Definition at line 1314 of file gnc-date.c.

01315 {
01316   struct tm tm;
01317 
01318   gnc_tm_get_day_end(&tm, time_val);
01319   return mktime(&tm);
01320 }

time_t gnc_timet_get_day_end_gdate GDate *  date  ) 
 

The gnc_timet_get_day_end() routine will take the given time in GLib GDate format and adjust it to the last second of that day.

Deprecated:

Definition at line 1341 of file gnc-date.c.

01342 {
01343   struct tm stm;
01344   time_t secs;
01345 
01346   stm.tm_year = g_date_year (date) - 1900;
01347   stm.tm_mon = g_date_month (date) - 1;
01348   stm.tm_mday = g_date_day (date);
01349   gnc_tm_set_day_end(&stm);
01350 
01351   /* Compute number of seconds */
01352   secs = mktime (&stm);
01353   return secs;
01354 }

time_t gnc_timet_get_day_start time_t  time_val  ) 
 

The gnc_timet_get_day_start() routine will take the given time in seconds and adjust it to the last second of that day.

Definition at line 1305 of file gnc-date.c.

01306 {
01307   struct tm tm;
01308 
01309   gnc_tm_get_day_start(&tm, time_val);
01310   return mktime(&tm);
01311 }

time_t gnc_timet_get_day_start_gdate GDate *  date  ) 
 

The gnc_timet_get_day_start() routine will take the given time in GLib GDate format and adjust it to the last second of that day.

Deprecated:

Definition at line 1325 of file gnc-date.c.

01326 {
01327   struct tm stm;
01328   time_t secs;
01329 
01330   stm.tm_year = g_date_year (date) - 1900;
01331   stm.tm_mon = g_date_month (date) - 1;
01332   stm.tm_mday = g_date_day (date);
01333   gnc_tm_set_day_start(&stm);
01334 
01335   /* Compute number of seconds */
01336   secs = mktime (&stm);
01337   return secs;
01338 }

time_t gnc_timet_get_today_end void   ) 
 

The gnc_timet_get_today_end() routine returns a time_t value corresponding to the last second of today.

Definition at line 1381 of file gnc-date.c.

01382 {
01383   struct tm tm;
01384 
01385   gnc_tm_get_day_end(&tm, time(NULL));
01386   return mktime(&tm);
01387 }

time_t gnc_timet_get_today_start void   ) 
 

The gnc_timet_get_today_start() routine returns a time_t value corresponding to the first second of today.

Definition at line 1372 of file gnc-date.c.

01373 {
01374   struct tm tm;
01375 
01376   gnc_tm_get_day_start(&tm, time(NULL));
01377   return mktime(&tm);
01378 }

long int gnc_timezone struct tm *  tm  ) 
 

The gnc_timezone function returns the number of seconds *west* of UTC represented by the tm argument, adjusted for daylight savings time.

This function requires a tm argument returned by localtime or set by mktime. This is a strange function! It requires that localtime or mktime be called before use. Subsequent calls to localtime or mktime *may* invalidate the result! The actual contents of tm *may* be used for both timezone offset and daylight savings time, or only daylight savings time! Timezone stuff under unix is not standardized and is a big mess.

Definition at line 1258 of file gnc-date.c.

01259 {
01260   g_return_val_if_fail (tm != NULL, 0);
01261 
01262 #ifdef HAVE_STRUCT_TM_GMTOFF
01263   /* tm_gmtoff is seconds *east* of UTC and is
01264    * already adjusted for daylight savings time. */
01265   return -(tm->tm_gmtoff);
01266 #else
01267   /* timezone is seconds *west* of UTC and is
01268    * not adjusted for daylight savings time.
01269    * In Spring, we spring forward, wheee! */
01270   return timezone - (tm->tm_isdst > 0 ? 60 * 60 : 0);
01271 #endif
01272 }

void gnc_tm_get_day_end struct tm *  tm,
time_t  time_val
 

The gnc_tm_get_day_end() routine will convert the given time in seconds to the struct tm format, and then adjust it to the last second of that day.

Definition at line 1297 of file gnc-date.c.

01298 {
01299   /* Get the equivalent time structure */
01300   tm = localtime_r(&time_val, tm);
01301   gnc_tm_set_day_end(tm);
01302 }

void gnc_tm_get_day_start struct tm *  tm,
time_t  time_val
 

The gnc_tm_get_day_start() routine will convert the given time in seconds to the struct tm format, and then adjust it to the first second of that day.

Definition at line 1289 of file gnc-date.c.

01290 {
01291   /* Get the equivalent time structure */
01292   tm = localtime_r(&time_val, tm);
01293   gnc_tm_set_day_start(tm);
01294 }

void gnc_tm_get_today_end struct tm *  tm  ) 
 

The gnc_tm_get_today_end() routine takes a pointer to a struct tm and fills it in with the last second of the today.

Definition at line 1366 of file gnc-date.c.

01367 {
01368   gnc_tm_get_day_end(tm, time(NULL));
01369 }

void gnc_tm_get_today_start struct tm *  tm  ) 
 

The gnc_tm_get_today_start() routine takes a pointer to a struct tm and fills it in with the first second of the today.

Definition at line 1360 of file gnc-date.c.

01361 {
01362   gnc_tm_get_day_start(tm, time(NULL));
01363 }

static void gnc_tm_set_day_end struct tm *  tm  )  [inline, static]
 

The gnc_tm_set_day_start() inline routine will set the appropriate fields in the struct tm to indicate the last second of that day. This routine assumes that the contents of the data structure is already in normalized form.

Definition at line 460 of file gnc-date.h.

00461 {
00462   /* Last second of the day */
00463   tm->tm_hour = 23;
00464   tm->tm_min = 59;
00465   tm->tm_sec = 59;
00466   tm->tm_isdst = -1;
00467 }

static void gnc_tm_set_day_middle struct tm *  tm  )  [inline, static]
 

The gnc_tm_set_day_start() inline routine will set the appropriate fields in the struct tm to indicate noon of that day. This routine assumes that the contents of the data structure is already in normalized form.

Definition at line 446 of file gnc-date.h.

00447 {
00448   /* First second of the day */
00449   tm->tm_hour = 12;
00450   tm->tm_min = 0;
00451   tm->tm_sec = 0;
00452   tm->tm_isdst = -1;
00453 }

static void gnc_tm_set_day_start struct tm *  tm  )  [inline, static]
 

The gnc_tm_set_day_start() inline routine will set the appropriate fields in the struct tm to indicate the first second of that day. This routine assumes that the contents of the data structure is already in normalized form.

Definition at line 432 of file gnc-date.h.

00433 {
00434   /* First second of the day */
00435   tm->tm_hour = 0;
00436   tm->tm_min = 0;
00437   tm->tm_sec = 0;
00438   tm->tm_isdst = -1;
00439 }

QofDateFormat qof_date_format_get void   ) 
 

The qof_date_format_get routine returns the date format that the date printing will use when printing a date, and the scaning routines will assume when parsing a date.

Returns:
: the one of the enumerated date formats.

Definition at line 341 of file gnc-date.c.

00342 {
00343   return dateFormat;
00344 }

const gchar* qof_date_format_get_string QofDateFormat  df  ) 
 

This function returns a strftime formatting string for printing an all numeric date (e.g. 2005-09-14). The string returned is based upon the location specified.

Parameters:
df The date style (us, uk, iso, etc) that should be provided.
Returns:
A formatting string that will print a date in the requested style

Definition at line 381 of file gnc-date.c.

00382 {
00383   switch(df) {
00384    case QOF_DATE_FORMAT_US:
00385     return "%m/%d/%y";
00386    case QOF_DATE_FORMAT_UK:
00387     return "%d/%m/%y";
00388    case QOF_DATE_FORMAT_CE:
00389     return "%d.%m.%y";
00390    case QOF_DATE_FORMAT_UTC:
00391     return "%Y-%m-%dT%H:%M:%SZ";
00392    case QOF_DATE_FORMAT_ISO:
00393     return "%y-%m-%d";
00394    case QOF_DATE_FORMAT_LOCALE:
00395    default:
00396     return GNC_D_FMT;
00397   };
00398 }

void qof_date_format_set QofDateFormat  df  ) 
 

The qof_date_format_set() routine sets date format to one of US, UK, CE, OR ISO. Checks to make sure it's a legal value. Args: QofDateFormat: enumeration indicating preferred format

Definition at line 357 of file gnc-date.c.

00358 {
00359   if(df >= DATE_FORMAT_FIRST && df <= DATE_FORMAT_LAST)
00360   {
00361     prevQofDateFormat = dateFormat;
00362     dateFormat = df;
00363   }
00364   else
00365   {    /* hack alert - Use a neutral default. */
00366     PERR("non-existent date format set attempted. Setting ISO default");
00367     prevQofDateFormat = dateFormat;
00368     dateFormat = QOF_DATE_FORMAT_ISO;
00369   }
00370 
00371   return;
00372 }

const gchar* qof_date_text_format_get_string QofDateFormat  df  ) 
 

This function returns a strftime formatting string for printing a date using words and numbers (e.g. 2005-September-14). The string returned is based upon the location specified.

Parameters:
df The date style (us, uk, iso, etc) that should be provided.
Returns:
A formatting string that will print a date in the requested style

Definition at line 409 of file gnc-date.c.

00410 {
00411   switch(df) {
00412    case QOF_DATE_FORMAT_US:
00413     return "%b %d, %y";
00414    case QOF_DATE_FORMAT_UK:
00415    case QOF_DATE_FORMAT_CE:
00416     return "%d %b, %y";
00417    case QOF_DATE_FORMAT_UTC:
00418     return "%Y-%m-%dT%H:%M:%SZ";
00419    case QOF_DATE_FORMAT_ISO:
00420     return "%y-%b-%d";
00421    case QOF_DATE_FORMAT_LOCALE:
00422    default:
00423     return GNC_D_FMT;
00424   };
00425 }

gboolean qof_is_same_day time_t  ,
time_t 
 

The qof_is_same_day() routine returns 0 if both times are in the same day.

Definition at line 695 of file gnc-date.c.

00696 {
00697   struct tm lta, ltb;
00698   lta = *localtime (&ta);
00699   ltb = *localtime (&tb);
00700   if (lta.tm_year == ltb.tm_year)
00701   {
00702     return (ltb.tm_yday - lta.tm_yday);
00703   }
00704   return (ltb.tm_year - lta.tm_year)*365;  /* very approximate */
00705 }

char* qof_print_date time_t  secs  ) 
 

Convenience; calls through to qof_print_date_dmy_buff(). Return: string, which should be freed when no longer needed.

Definition at line 520 of file gnc-date.c.

00521 {
00522    char buff[MAX_DATE_LENGTH];
00523    qof_print_date_buff (buff, MAX_DATE_LENGTH, t);
00524    return g_strdup (buff);
00525 }

size_t qof_print_date_buff char *  buff,
size_t  buflen,
time_t  secs
 

Convenience: calls through to qof_print_date_dmy_buff().

Definition at line 496 of file gnc-date.c.

00497 {
00498   struct tm *theTime;
00499 
00500   if (!buff) return 0 ;
00501 
00502   theTime = localtime (&t);
00503 
00504   return qof_print_date_dmy_buff (buff, len,
00505                    theTime->tm_mday, 
00506                    theTime->tm_mon + 1,
00507                    theTime->tm_year + 1900);
00508 }

size_t qof_print_date_dmy_buff char *  buff,
size_t  buflen,
int  day,
int  month,
int  year
 

qof_print_date_dmy_buff Convert a date as day / month / year integers into a localized string representation

Args: buff - pointer to previously allocated character array; its size must be at lease MAX_DATE_LENTH bytes. len - length of the buffer, in bytes. day - day of the month as 1 ... 31 month - month of the year as 1 ... 12 year - year (4-digit)

Returns: number of characters printed

Globals: global dateFormat value

Definition at line 443 of file gnc-date.c.

00444 {
00445   int flen;
00446   if (!buff) return 0;
00447 
00448   /* Note that when printing year, we use %-4d in format string;
00449    * this causes a one, two or three-digit year to be left-adjusted
00450    * when printed (i.e. padded with blanks on the right).  This is 
00451    * important while the user is editing the year, since erasing a 
00452    * digit can temporarily cause a three-digit year, and having the 
00453    * blank on the left is a real pain for the user.  So pad on the 
00454    * right.
00455    */
00456   switch(dateFormat)
00457   {
00458     case QOF_DATE_FORMAT_UK:
00459       flen = g_snprintf (buff, len, "%2d/%2d/%-4d", day, month, year);
00460       break;
00461     case QOF_DATE_FORMAT_CE:
00462       flen = g_snprintf (buff, len, "%2d.%2d.%-4d", day, month, year);
00463       break;
00464     case QOF_DATE_FORMAT_LOCALE:
00465       {
00466         struct tm tm_str;
00467         time_t t;
00468 
00469         tm_str.tm_mday = day;
00470         tm_str.tm_mon = month - 1;    /* tm_mon = 0 through 11 */
00471         tm_str.tm_year = year - 1900; /* this is what the standard 
00472                                        * says, it's not a Y2K thing */
00473 
00474         gnc_tm_set_day_start (&tm_str);
00475         t = mktime (&tm_str);
00476         localtime_r (&t, &tm_str);
00477         flen = strftime (buff, len, GNC_D_FMT, &tm_str);
00478        if (flen != 0)
00479          break;
00480       }
00481       /* FALLTHROUGH */
00482     case QOF_DATE_FORMAT_ISO:
00483     case QOF_DATE_FORMAT_UTC:
00484       flen = g_snprintf (buff, len, "%04d-%02d-%02d", year, month, day);
00485       break;
00486     case QOF_DATE_FORMAT_US:
00487     default:
00488       flen = g_snprintf (buff, len, "%2d/%2d/%-4d", month, day, year);
00489       break;
00490   }
00491 
00492   return flen;
00493 }

size_t qof_print_gdate char *  buf,
size_t  bufflen,
GDate *  gd
 

Convenience; calls through to qof_print_date_dmy_buff().

Definition at line 511 of file gnc-date.c.

00512 {
00513   return qof_print_date_dmy_buff( buf, len,
00514              g_date_day(gd),
00515              g_date_month(gd),
00516              g_date_year(gd) );
00517 }

size_t qof_print_hours_elapsed_buff char *  buff,
size_t  len,
int  secs,
gboolean  show_secs
 

The qof_print_hours_elapsed_buff() routine will print the 'secs' argument as HH:MM, and will print the seconds if show_secs is true. Thus, for example, secs=3599 will print as 0:59 Returns the number of bytes copied.

Definition at line 543 of file gnc-date.c.

00544 {
00545         size_t flen;
00546         if (0 <= secs)
00547         {
00548                 if (show_secs)
00549                 {
00550                         flen = g_snprintf(buff, len,
00551                            "%02d:%02d:%02d", (int)(secs / 3600),
00552                            (int)((secs % 3600) / 60), (int)(secs % 60));
00553                 }
00554                 else
00555                 {
00556                         flen = g_snprintf(buff, len, 
00557                            "%02d:%02d", (int)(secs / 3600),
00558                            (int)((secs % 3600) / 60));
00559                 }
00560         } 
00561         else 
00562         {
00563                 if (show_secs)
00564                 {
00565                         flen = g_snprintf(buff, len,
00566                            "-%02d:%02d:%02d", (int)(-secs / 3600),
00567                            (int)((-secs % 3600) / 60), (int)(-secs % 60));
00568                 }
00569                 else
00570                 {
00571                         flen = g_snprintf(buff, len,
00572                            "-%02d:%02d", (int)(-secs / 3600),
00573                            (int)((-secs % 3600) / 60));
00574                 }
00575         }
00576         return flen;
00577 }

size_t qof_print_time_buff char *  buff,
size_t  len,
time_t  secs
 

The qof_print_time_buff() routine prints only the hour-part of the date. Thus, if secs is ... Returns the number of bytes printed.

Definition at line 674 of file gnc-date.c.

00675 {
00676   int flen;
00677         struct tm ltm, gtm;
00678   
00679   if (!buff) return 0;
00680         if(dateFormat == QOF_DATE_FORMAT_UTC)
00681         {
00682                 gtm = *gmtime (&secs);
00683                 flen = strftime(buff, len, QOF_UTC_DATE_FORMAT, &gtm);
00684                 return flen;
00685         }
00686   ltm = *localtime (&secs);
00687   flen = strftime (buff, len, GNC_T_FMT, &ltm);
00688 
00689   return flen;
00690 }

gboolean qof_scan_date const char *  buff,
int *  day,
int *  month,
int *  year
 

qof_scan_date Convert a string into day / month / year integers according to the current dateFormat value.

Args: buff - pointer to date string day - will store day of the month as 1 ... 31 month - will store month of the year as 1 ... 12 year - will store the year (4-digit)

Return: TRUE if the string seemed to be a valid date; else FALSE.

Globals: uses global dateFormat value to assist in parsing.

Definition at line 900 of file gnc-date.c.

00901 {
00902   return qof_scan_date_internal(buff, day, month, year, dateFormat);
00903 }

gboolean qof_scan_date_secs const char *  buff,
time_t *  secs
 

as above, but returns seconds

Definition at line 906 of file gnc-date.c.

00907 {
00908   gboolean rc;
00909   int day, month, year;
00910   
00911   rc = qof_scan_date_internal(buff, &day, &month, &year, dateFormat);
00912   if (secs) *secs = xaccDMYToSec (day, month, year);
00913 
00914   return rc;
00915 }

Timespec timespec_abs const Timespec t  ) 
 

absolute value, also normalised

Definition at line 224 of file gnc-date.c.

00225 {
00226   Timespec retval = *t;
00227 
00228   timespec_normalize(&retval);
00229   if (retval.tv_sec < 0)
00230   {
00231     retval.tv_sec = - retval.tv_sec;
00232     retval.tv_nsec = - retval.tv_nsec;
00233   }
00234   
00235   return retval;
00236 }

int timespec_cmp const Timespec ta,
const Timespec tb
 

comparison: if (ta < tb) -1; else if (ta > tb) 1; else 0;

Definition at line 203 of file gnc-date.c.

00204 {
00205   if(ta == tb) return 0;
00206   if(ta->tv_sec < tb->tv_sec) return -1;
00207   if(ta->tv_sec > tb->tv_sec) return 1;
00208   if(ta->tv_nsec < tb->tv_nsec) return -1;
00209   if(ta->tv_nsec > tb->tv_nsec) return 1;
00210   return 0;
00211 }

Timespec timespec_diff const Timespec ta,
const Timespec tb
 

difference between ta and tb, results are normalised ie tv_sec and tv_nsec of the result have the same size abs(result.tv_nsec) <= 1000000000

Definition at line 214 of file gnc-date.c.

00215 {
00216   Timespec retval;
00217   retval.tv_sec = ta->tv_sec - tb->tv_sec;
00218   retval.tv_nsec = ta->tv_nsec - tb->tv_nsec;
00219   timespec_normalize(&retval);
00220   return retval;
00221 }

gboolean timespec_equal const Timespec ta,
const Timespec tb
 

strict equality

Definition at line 194 of file gnc-date.c.

00195 {
00196   if(ta == tb) return TRUE;
00197   if(ta->tv_sec != tb->tv_sec) return FALSE;
00198   if(ta->tv_nsec != tb->tv_nsec) return FALSE;
00199   return TRUE;
00200 }

Timespec timespecCanonicalDayTime Timespec  t  ) 
 

convert a timepair on a certain day (localtime) to the timepair representing midday on that day

Definition at line 244 of file gnc-date.c.

00245 {
00246   struct tm tm, *result;
00247   Timespec retval;
00248   time_t t_secs = t.tv_sec + (t.tv_nsec / NANOS_PER_SECOND);
00249   result = localtime(&t_secs);
00250   tm = *result;
00251   gnc_tm_set_day_middle(&tm);
00252   retval.tv_sec = mktime(&tm);
00253   retval.tv_nsec = 0;
00254   return retval;
00255 }

void timespecFromTime_t Timespec ts,
time_t  t
 

Turns a time_t into a Timespec

Definition at line 1276 of file gnc-date.c.

01277 {
01278     ts->tv_sec = t;
01279     ts->tv_nsec = 0;
01280 }

time_t timespecToTime_t Timespec  ts  ) 
 

Turns a Timespec into a time_t

Definition at line 1283 of file gnc-date.c.

01284 {
01285     return ts.tv_sec;
01286 }

char* xaccDateUtilGetStamp time_t  thyme  ) 
 

The xaccDateUtilGetStamp() routine will take the given time in seconds and return a buffer containing a textual for the date.

Parameters:
thyme The time in seconds to convert.
Returns:
A pointer to the generated string.
Note:
The caller owns this buffer and must free it when done.

Definition at line 971 of file gnc-date.c.

00972 {
00973    struct tm *stm;
00974                                                                                 
00975    stm = localtime (&thyme);
00976                                                                                 
00977    return g_strdup_printf("%04d%02d%02d%02d%02d%02d",
00978       (stm->tm_year + 1900),
00979       (stm->tm_mon +1),
00980       stm->tm_mday,
00981       stm->tm_hour,
00982       stm->tm_min,
00983       stm->tm_sec
00984    );
00985 }

char* xaccDateUtilGetStampNow void   ) 
 

The xaccDateUtilGetStampNow() routine returns the current time in seconds in textual format.

Returns:
A pointer to the generated string.
Note:
The caller owns this buffer and must free it when done.

Definition at line 998 of file gnc-date.c.

00999 {
01000    time_t now;
01001    time (&now);
01002    return xaccDateUtilGetStamp (now);
01003 }

time_t xaccDMYToSec int  day,
int  month,
int  year
 

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 ...
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.

Definition at line 1183 of file gnc-date.c.

01184 {
01185   struct tm stm;
01186   time_t secs;
01187 
01188   stm.tm_year = year - 1900;
01189   stm.tm_mon = month - 1;
01190   stm.tm_mday = day;
01191   gnc_tm_set_day_start(&stm);
01192 
01193   /* compute number of seconds */
01194   secs = mktime (&stm);
01195 
01196   return secs;
01197 }


Generated on Fri Oct 21 15:49:58 2005 for QOF by  doxygen 1.4.5