Date: 64bit UTC date handling.
[Time: 64bit UTC Time handling.]


Detailed Description

All dates in QOF use Universal Coordinated Time, (UTC), wrapped to allow representation of dates before the epoch.

localtime is available via GDate but there are limitations.

  1. The GDate data structure represents a day between January 1, Year 1, and sometime a few thousand years in the future, not the full range of QofTime.
  2. Right now GDate will go to the year 65535 or so, but g_date_set_parse() only parses up to the year 8000 or so - just count on "a few thousand".
  3. g_date_strftime only deals with date related formats, results of using time formats is undefined.

A QofDateEntry is one a collection of formats for handling dates, including common defaults. New entries need to be registered using qof_date_add_format before being used to print or scan strings containing dates.

Todo:
Add support for customised handlers for added formats.
A QofDate is theoretically able to go forward to the year 292,471,206,707 AD and back to the year 292,471,206,708 BC. Whether such dates actually exist is outside the scope of this documentation.

Note:
Time moves at a constant rate, dates do not. Dates are inherently tied to the rotation of the Earth and that rotation is slowing down, causing the need for leapseconds. The incidence of leapseconds cannot be accurately predicted and dates far into the future may be out by a number of seconds. This is important if future dates are based around the start (or end) of a particular day - when those dates come to be viewed as the past, the actual day calculated from the number of seconds may differ to the day originally calculated. When using future dates, avoid using dates at the start or end of a particular day.
Since:
v0.7.0


Files

file  qofdate.h
 64bit Date handling routines

Data Structures

struct  QofDate_s
 Full range replacement for struct tm. More...

Default QofDate formats

#define QOF_DATE_FORMAT_US   1
 Continental US default. "%m/%d/%Y".
#define QOF_DATE_FORMAT_UK   2
 United Kingdom default. "%d/%m/%Y".
#define QOF_DATE_FORMAT_CE   3
 Contintental European default. "%d.%m.%Y".
#define QOF_DATE_FORMAT_ISO   4
 Short ISO form. "%F".
#define QOF_DATE_FORMAT_UTC   5
 QOF UTC format, xsd:date compatible. QOF_UTC_DATE_FORMAT "%Y-%m-%dT%H:%M:%SZ".
#define QOF_DATE_FORMAT_ISO8601   6
#define QOF_DATE_FORMAT_LOCALE   7
 GNU locale default. "%x".
#define QOF_DATE_FORMAT_CUSTOM   8
 Date and time for the current locale "%c".
#define DATE_FORMAT_LAST   QOF_DATE_FORMAT_CUSTOM

QofDateFormat - standardised date formats

To simplify usage of strftime and strptime (especially checking error states), QofDate uses a set of standard date formats. You can also register your own format strings as long as they are strftime compatible.

see also QofDate and locales.

gboolean qof_date_format_add (const gchar *str, QofDateFormat *identifier)
 Add a specific strftime compatible string as a new QofDateFormat.
const gchar * qof_date_format_to_name (QofDateFormat format)
 Retrieve the shorthand name for the selected date format.
QofDateFormat qof_date_format_from_name (const gchar *name)
 Returns the default date format for a known shorthand name.
gboolean qof_date_format_set_name (const gchar *name, QofDateFormat format)
 Set a shorthand name for a custom date format.
QofDateFormat qof_date_format_get_current (void)
 returns the current date format.
gboolean qof_date_format_set_current (QofDateFormat df)
 Selects one registered date format as the current default.
const gchar * qof_date_format_get_format (QofDateFormat df)
 Retrieve the strftime format string for a registered date format.
gchar qof_date_format_get_date_separator (QofDateFormat df)
 Return the field separator for the current date format.
gboolean qof_date_format_set_date_separator (const gchar sep, QofDateFormat df)
 Set a locale-specific separator.

QofDate handlers

QofDateqof_date_new (void)
QofDateqof_date_get_current (void)
QofDateqof_date_new_dmy (gint day, gint month, gint64 year)
void qof_date_free (QofDate *date)
QofTimeqof_date_time_difference (const QofDate *date1, const QofDate *date2)
gboolean qof_date_is_last_mday (const QofDate *qd)
gboolean qof_date_addmonths (QofDate *qd, gint months, gboolean track_last_day)
gboolean qof_date_equal (const QofDate *d1, const QofDate *d2)
gint qof_date_compare (const QofDate *d1, const QofDate *d2)
gboolean qof_date_valid (QofDate *date)
 Validate a QofDate.
guint16 qof_date_get_yday (gint mday, gint month, gint64 year)
guint8 qof_date_get_mday (gint month, gint64 year)

Conversion handlers for QofDate

QofDateqof_date_from_qtime (const QofTime *qt)
QofTimeqof_date_to_qtime (const QofDate *qd)
QofDateqof_date_from_struct_tm (const struct tm *stm)
 Convert a struct tm to a QofDate.
gboolean qof_date_to_struct_tm (const QofDate *qt, struct tm *stm, glong *nanosecs)
 Convert a QofDate to a struct tm.
gboolean qof_date_to_gdate (const QofDate *qd, GDate *gd)
 Convert a QofDate to a GDate.
QofDateqof_date_from_gdate (const GDate *gd)
 Create a QofDate from a GDate.

Manipulate QofTime as a date

Shorthand routines to modify a QofTime using date-type values, instead of having to always use seconds.

gboolean qof_date_adddays (QofDate *qd, gint days)
 Add a number of days to a QofDate and normalise.
gboolean qof_date_set_day_end (QofDate *qd)
gboolean qof_date_set_day_start (QofDate *qd)
gboolean qof_date_set_day_middle (QofDate *qd)

Date Printing/Scanning functions

QofDate supports a wider range of dates than either strftime or GDate and supports all non-locale-specific strftime format specifiers over the full range of QofDate.

Note:
Locale-specific formats cannot be extended to the full range of QofDate dates because the locale data for these formats is only available to the underlying strftime implementation. The formats affected are those involving the E and O modifiers and other format specifiers that use the current locale. e.g. Japanese Emperor reigns, local numeric specifiers, translated days of the week / month etc. If these are used, only dates within the range of the locale-sensitive strftime on that platform can be supported (either inside or outside QofDate).
The full list of affected format specifiers is:

'a', 'A', 'b', 'h', 'B', 'c', 'C', 'x', 'p', 'P', 'r', 'X', 'E', 'O'.
 

QofDate will attempt to fallback to a usable format if the date is out of range of the underlying strftime. e.g. QOF_DATE_FORMAT_UTC, QOF_DATE_FORMAT_UK, QOF_DATE_FORMAT_US, QOF_DATE_FORMAT_CE or QOF_DATE_FORMAT_ISO.

Note:
It is not particularly sensible to write locale-sensitive date strings to any kind of permanent storage. Locale-specific format specifiers should only be used for displaying dates to the user.
For more information, see QofDate and locales.

  • Scanning: Convert a timestamp into a QofTime*
    1. To scan a string yourself, use qof_date_format_get_format to get the format to pass to strptime or use g_date_set_parse
    2. To scan a stamp created with a registered date format, use qof_date_parse


gchar * qof_date_print (const QofDate *date, QofDateFormat df)
 Convert a QofDate to a timestamp according to the specified date format.
QofDateqof_date_parse (const gchar *str, QofDateFormat df)
 Convert a timestamp to a QofTime.

Defines

#define MAX_DATE_LENGTH   41
 The maximum length of a string used for or created by dates.
#define MAX_DATE_BUFFER   256
 The maximum length of a QofDate buffer.
#define SECS_PER_DAY   86400
#define SECS_PER_HOUR   3600
#define QOF_MOD_DATE   "qof-dates"
#define qof_date_isleap(year)   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
#define QOF_UTC_DATE_FORMAT   "%Y-%m-%dT%H:%M:%SZ"
 UTC date format string.
#define QOF_HOUR_TO_SEC(x)   (x * SECS_PER_HOUR)
#define QOF_MIN_TO_SEC(x)   (x * 60)
#define QOF_DAYS_TO_SEC(x)   (x * SECS_PER_DAY)

Typedefs

typedef QofDate_s QofDate
 Full range replacement for struct tm.
typedef gint QofDateFormat

Functions

void qof_date_init (void)
 initialise the QofDate tables
void qof_date_close (void)
 close down the QofDate tables


Define Documentation

#define DATE_FORMAT_LAST   QOF_DATE_FORMAT_CUSTOM
 

New identifiers must be larger than this.

Definition at line 322 of file qofdate.h.

#define MAX_DATE_BUFFER   256
 

The maximum length of a QofDate buffer.

Todo:
rationalise with MAX_DATE_LENGTH

Definition at line 92 of file qofdate.h.

#define MAX_DATE_LENGTH   41
 

The maximum length of a string used for or created by dates.

When setting a custom QofDateFormat, neither the format string itself nor any date string created from that format is allowed to exceed this length.

Definition at line 87 of file qofdate.h.

#define QOF_DATE_FORMAT_CE   3
 

Contintental European default. "%d.%m.%Y".

9th May 2006 == 09.05.2006

Definition at line 263 of file qofdate.h.

#define QOF_DATE_FORMAT_CUSTOM   8
 

Date and time for the current locale "%c".

QOF_DATE_FORMAT_LOCALE and QOF_DATE_FORMAT_CUSTOM are only suitable for date / time display - storing these values in any kind of file is a recipe for disaster as the exact format can be affected by environment variables and other imponderables.

One example: 9th May 2006 gives Tue 09 May 2006 14:50:10 UTC

Note:
QOF_DATE_FORMAT_CUSTOM includes locale-specific format specifiers and therefore cannot support the full range of QofDate. see QofDate and locales.

Definition at line 319 of file qofdate.h.

#define QOF_DATE_FORMAT_ISO   4
 

Short ISO form. "%F".

9th May 2006 == 2006-05-09

Definition at line 268 of file qofdate.h.

#define QOF_DATE_FORMAT_ISO8601   6
 

Date and time with nanoseconds and timezone.

"%Y-%m-%d %H:%M:%S.%N %z"

12th July 2006 gives 2006-07-12 17:08:16.329768000 +0000 in UTC. Timezones can be specified and will then be converted into UTC at validation.

Definition at line 287 of file qofdate.h.

#define QOF_DATE_FORMAT_LOCALE   7
 

GNU locale default. "%x".

QOF_DATE_FORMAT_LOCALE and QOF_DATE_FORMAT_CUSTOM are only suitable for date / time display - storing these values in any kind of file is a recipe for disaster as the exact format can be affected by environment variables and other imponderables.

One example: 9th May 2006 gives 09/05/06

Note:
QOF_DATE_FORMAT_LOCALE includes locale-specific format specifiers and therefore cannot support the full range of QofDate. see QofDate and locales.

Definition at line 303 of file qofdate.h.

#define QOF_DATE_FORMAT_UK   2
 

United Kingdom default. "%d/%m/%Y".

9th May 2006 == 09/05/2006

Definition at line 258 of file qofdate.h.

#define QOF_DATE_FORMAT_US   1
 

Continental US default. "%m/%d/%Y".

9th May 2006 == 05/09/2006

Definition at line 253 of file qofdate.h.

#define QOF_DATE_FORMAT_UTC   5
 

QOF UTC format, xsd:date compatible. QOF_UTC_DATE_FORMAT "%Y-%m-%dT%H:%M:%SZ".

xsd:date is recommended for any XML data storage of dates and times.

9th May 2006 == 2006-05-09T14:49:04Z

Definition at line 277 of file qofdate.h.

#define qof_date_isleap year   )     ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
 

Nonzero if YEAR is a leap year (every 4 years, except every 100th isn't, and every 400th is).

Definition at line 222 of file qofdate.h.

#define QOF_DAYS_TO_SEC  )     (x * SECS_PER_DAY)
 

convenience macro to turn days into seconds.

Definition at line 331 of file qofdate.h.

#define QOF_HOUR_TO_SEC  )     (x * SECS_PER_HOUR)
 

convenience macro to turn hours into seconds.

Definition at line 327 of file qofdate.h.

#define QOF_MIN_TO_SEC  )     (x * 60)
 

convenience macro to turn minutes into seconds.

Definition at line 329 of file qofdate.h.

#define QOF_MOD_DATE   "qof-dates"
 

QofLogModule name for QofDate

Definition at line 98 of file qofdate.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-%dT%H: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 244 of file qofdate.h.

#define SECS_PER_DAY   86400
 

number of seconds in one whole day.

Definition at line 94 of file qofdate.h.

#define SECS_PER_HOUR   3600
 

number of seconds in one whole hour.

Definition at line 96 of file qofdate.h.


Typedef Documentation

typedef struct QofDate_s QofDate
 

Full range replacement for struct tm.

Based on struct tm but using signed integers. The year value uses a signed 64bit value to prevent overflows. (A glong is insufficient by two orders of magnitude.) To retain precision, a QofDate includes a nanoseconds value that can be used with a QofTime and a 64bit value for seconds.

Note:
All QofDate values can be negative. The normalising cascade handles rollovers. e.g. If a QofDate qd_min value is 5 initially, setting qd_sec to 68 causes qd_sec to actually hold the value 8 and qd_min to hold the value 6. Alternatively, setting qd_sec to -64 with qd_min set to 5 causes qd_sec to hold the value 56 and qd_min to hold the value 3.
Todo:
check - years work like this, days don't!! Only qd_year retains a negative value once set. Adding one year to a negative QofDate causes the QofDate to be set to one year further into the past. This follows the same pattern as typical BC dates: the 1st of May 501BC is further into the past than the 5th of May 500BC.
Why is this a date? Because it represents a date, broken down into the component variables. A QofTime always (and only) relates to seconds, a QofDate always relates to how that number of seconds can be represented as a sequence of days, months, years etc.

Note:
Although values can be set directly, qof_date_valid should be called before attempting to manipulate a QofDate.
Todo:
Reorganise the qof_time_* functions to reflect this statement. qof_time_set_day_end should be qof_date_set_day_end and the various qof_date_time functions need to be reviewed.

typedef gint QofDateFormat
 

Index value of the selected QofDateFormat in the DateFormatTable

Definition at line 335 of file qofdate.h.


Function Documentation

gboolean qof_date_adddays QofDate qd,
gint  days
 

Add a number of days to a QofDate and normalise.

Parameters:
qd A valid QofDate.
days Number of days to add - use negative value to subtract.
Returns:
FALSE on error, otherwise TRUE.

Definition at line 961 of file qofdate.c.

00962 {
00963     g_return_val_if_fail (qd, FALSE);
00964     g_return_val_if_fail (qof_date_valid (qd), FALSE);
00965     qd->qd_mday += days;
00966     return qof_date_valid (qd);
00967 }

gboolean qof_date_addmonths QofDate qd,
gint  months,
gboolean  track_last_day
 

Add (or subtract) months from a QofDate

Optionally tracks the last day of the month so that if the original QofDate is the last day of the month in the specified year, the updated QofDate will also be the last day of the updated month in the updated year.

Parameters:
qd A QofDate which will be normalised before calculations begin.
months Number of months to add (or subtract if months is negative).
track_last_day Whether to track the last day.
Returns:
FALSE on error, otherwise TRUE.

Definition at line 970 of file qofdate.c.

00972 {
00973     g_return_val_if_fail (qd, FALSE);
00974     g_return_val_if_fail (qof_date_valid (qd), FALSE);
00975     qd->qd_mon += months % 12;
00976     qd->qd_year += months / 12;
00977     g_return_val_if_fail (qof_date_valid (qd), FALSE);
00978     if (track_last_day && qof_date_is_last_mday (qd))
00979     {
00980         qd->qd_mday = qof_date_get_mday (qd->qd_mon,
00981             qd->qd_year);
00982     }
00983     return TRUE;
00984 }

gint qof_date_compare const QofDate d1,
const QofDate d2
 

Compare two QofDates

Definition at line 634 of file qofdate.c.

00635 {
00636     if ((!d1) && (!d2))
00637         return 0;
00638     if (d1 == d2)
00639         return 0;
00640     if (!d1)
00641         return -1;
00642     if (!d2)
00643         return 1;
00644     if (d1->qd_year < d2->qd_year)
00645         return -1;
00646     if (d1->qd_year > d2->qd_year)
00647         return 1;
00648     if (d1->qd_mon < d2->qd_mon)
00649         return -1;
00650     if (d1->qd_mon > d2->qd_mon)
00651         return 1;
00652     if (d1->qd_mday < d2->qd_mday)
00653         return -1;
00654     if (d1->qd_mday > d2->qd_mday)
00655         return 1;
00656     if (d1->qd_hour < d2->qd_hour)
00657         return -1;
00658     if (d1->qd_hour > d2->qd_hour)
00659         return 1;
00660     if (d1->qd_min < d2->qd_min)
00661         return -1;
00662     if (d1->qd_min > d2->qd_min)
00663         return 1;
00664     if (d1->qd_sec < d2->qd_sec)
00665         return -1;
00666     if (d1->qd_sec > d2->qd_sec)
00667         return 1;
00668     if (d1->qd_nanosecs < d2->qd_nanosecs)
00669         return -1;
00670     if (d1->qd_nanosecs > d2->qd_nanosecs)
00671         return 1;
00672     return 0;
00673 }

gboolean qof_date_equal const QofDate d1,
const QofDate d2
 

Check two QofDates for equality

Definition at line 626 of file qofdate.c.

00627 {
00628     if (0 == qof_date_compare (d1, d2))
00629         return TRUE;
00630     return FALSE;
00631 }

gboolean qof_date_format_add const gchar *  str,
QofDateFormat identifier
 

Add a specific strftime compatible string as a new QofDateFormat.

Todo:
Move to QofDate and qofgmtime_r

Definition at line 200 of file qofdate.c.

00201 {
00202     struct tm check;
00203     gint len;
00204     time_t now;
00205     gchar test[MAX_DATE_BUFFER];
00206 
00208     g_return_val_if_fail (QofDateInit, FALSE);
00209     g_return_val_if_fail (str, FALSE);
00210     g_return_val_if_fail (strlen (str) != 0, FALSE);
00211     /* prevent really long strings being passed */
00212     ENTER (" str=%s", str);
00213     if (strlen (str) > MAX_DATE_LENGTH)
00214     {
00215         LEAVE (" '%s' is too long! Max=%d str_len=%d",
00216             str, MAX_DATE_LENGTH, (gint) strlen (str));
00217         return FALSE;
00218     }
00219     /* test the incoming string using the current time. */
00220     now = time (NULL);
00221     test[0] = '\1';
00222     check = *gmtime_r (&now, &check);
00223     /* need to allow time related formats - 
00224     don't use g_date_strftime here. */
00225     len = strftime (test, (MAX_DATE_BUFFER - 1), str, &check);
00226     if (len == 0 && test[0] != '\0')
00227     {
00228         LEAVE (" strftime could not understand '%s'", str);
00229         return FALSE;
00230     }
00231     len = strlen (test);
00232     if (len > MAX_DATE_LENGTH)
00233     {
00234         LEAVE (" %s creates a string '%s' that is too long!"
00235             " Max=%d str_len=%d", str, test, MAX_DATE_LENGTH, len);
00236         return FALSE;
00237     }
00238     *identifier = g_hash_table_size (DateFormatTable) + 1;
00239     {
00240         QofDateEntry *d = g_new0 (QofDateEntry, 1);
00241         d->format = str;
00242         d->name = str;
00243         d->separator = locale_separator;
00244         d->df = *identifier;
00245         g_hash_table_insert (DateFormatTable, GINT_TO_POINTER (d->df), d);
00246     }
00247     LEAVE (" successful");
00248     return TRUE;
00249 }

QofDateFormat qof_date_format_from_name const gchar *  name  ) 
 

Returns the default date format for a known shorthand name.

If the selected QofDateFormat is one of the defaults, the shorthand "name" is returned. If format is not a default, returns negative one.

Parameters:
name Shorthand "name" of this format.
Returns:
the QofDateFormat on success, negative one on failure.

Definition at line 382 of file qofdate.c.

00383 {
00384     struct iter i;
00385 
00386     if (!name)
00387         return -1;
00388     if (0 == safe_strcmp (name, "us"))
00389         return QOF_DATE_FORMAT_US;
00390     if (0 == safe_strcmp (name, "uk"))
00391         return QOF_DATE_FORMAT_UK;
00392     if (0 == safe_strcmp (name, "ce"))
00393         return QOF_DATE_FORMAT_CE;
00394     if (0 == safe_strcmp (name, "utc"))
00395         return QOF_DATE_FORMAT_UTC;
00396     if (0 == safe_strcmp (name, "iso"))
00397         return QOF_DATE_FORMAT_ISO;
00398     if (0 == safe_strcmp (name, "locale"))
00399         return QOF_DATE_FORMAT_LOCALE;
00400     if (0 == safe_strcmp (name, "custom"))
00401         return QOF_DATE_FORMAT_CUSTOM;
00402     i.name = name;
00403     i.df = -1;
00404     g_hash_table_foreach (DateFormatTable, lookup_name, &i);
00405     return i.df;
00406 }

gchar qof_date_format_get_date_separator QofDateFormat  df  ) 
 

Return the field separator for the current date format.

Note:
The separator only relates to the date portion of any date format string, i.e. the separator used between day, month and year. Separators used between time fields like hour, minute, second in any date format are not available.
Returns:
date single non-digit character to separate fields within the date section of a date format or a null on error.

Definition at line 323 of file qofdate.c.

00324 {
00325     QofDateEntry *d;
00326 
00327     g_return_val_if_fail (QofDateInit, locale_separator);
00328     d = g_hash_table_lookup (DateFormatTable, GINT_TO_POINTER (df));
00329     if (!d)
00330     {
00331         PERR (" unknown format: '%d'", df);
00332         return locale_separator;
00333     }
00334     return d->separator;
00335 }

const gchar* qof_date_format_get_format QofDateFormat  df  ) 
 

Retrieve the strftime format string for a registered date format.

Parameters:
df The QofDateFormat identifier for the registered date format.
Returns:
The format string for this date format or NULL on error.

Definition at line 308 of file qofdate.c.

00309 {
00310     QofDateEntry *d;
00311 
00312     g_return_val_if_fail (QofDateInit, NULL);
00313     d = g_hash_table_lookup (DateFormatTable, GINT_TO_POINTER (df));
00314     if (!d)
00315     {
00316         PERR (" unknown format: '%d'", df);
00317         return NULL;
00318     }
00319     return d->format;
00320 }

gboolean qof_date_format_set_current QofDateFormat  df  ) 
 

Selects one registered date format as the current default.

Parameters:
df QofDateFormat identifier indicating preferred format.
Returns:
TRUE on success, else FALSE.

Definition at line 292 of file qofdate.c.

00293 {
00294     QofDateEntry *d;
00295 
00296     g_return_val_if_fail (QofDateInit, FALSE);
00297     d = g_hash_table_lookup (DateFormatTable, GINT_TO_POINTER (df));
00298     if (!d)
00299     {
00300         PERR (" unknown format: '%d'", df);
00301         return FALSE;
00302     }
00303     dateFormat = d->df;
00304     return TRUE;
00305 }

gboolean qof_date_format_set_date_separator const gchar  sep,
QofDateFormat  df
 

Set a locale-specific separator.

Sets the date separator for a date format added using qof_date_format_add.

Returns:
FALSE if date format is not one of the QOF defaults or if the character is a digit, TRUE on success.

Definition at line 338 of file qofdate.c.

00339 {
00340     QofDateEntry *d;
00341 
00342     g_return_val_if_fail (QofDateInit, FALSE);
00343     if (df < DATE_FORMAT_LAST)
00344     {
00345         DEBUG (" Prevented attempt to override a default format");
00346         return FALSE;
00347     }
00348     if (g_ascii_isdigit (sep))
00349         return FALSE;
00350     d = g_hash_table_lookup (DateFormatTable, GINT_TO_POINTER (df));
00351     if (!d)
00352     {
00353         PERR (" unknown format: '%d'", df);
00354         return FALSE;
00355     }
00356     d->separator = sep;
00357     g_hash_table_insert (DateFormatTable, GINT_TO_POINTER (df), d);
00358     return TRUE;
00359 }

gboolean qof_date_format_set_name const gchar *  name,
QofDateFormat  format
 

Set a shorthand name for a custom date format.

Used alongside qof_date_format_add to allow any date format to have a shorthand name.

Parameters:
name Shorthand name for a date format added with qof_date_format_add. The string becomes the property of QofDate and should not be freed.
format identifier used previously with qof_date_format_add
Returns:
TRUE if the shorthand name can be set, FALSE on error or if the chosen QofDateFormat is one of the defaults.

Definition at line 267 of file qofdate.c.

00268 {
00269     QofDateEntry *d;
00270 
00271     g_return_val_if_fail (QofDateInit, FALSE);
00272     if (format <= DATE_FORMAT_LAST)
00273         return FALSE;
00274     d = g_hash_table_lookup (DateFormatTable, GINT_TO_POINTER (format));
00275     if (!d)
00276     {
00277         PERR (" unknown format: '%d'", format);
00278         return FALSE;
00279     }
00280     d->name = name;
00281     g_hash_table_insert (DateFormatTable, GINT_TO_POINTER (format), d);
00282     return TRUE;
00283 }

const gchar* qof_date_format_to_name QofDateFormat  format  ) 
 

Retrieve the shorthand name for the selected date format.

If the selected QofDateFormat is one of the defaults, a shorthand "name" is used. If it is a string added using qof_date_add_format, the string itself is returned.

Parameters:
format The QofDateFormat to lookup.
Returns:
FALSE on success and TRUE on failure.

Definition at line 252 of file qofdate.c.

00253 {
00254     QofDateEntry *d;
00255 
00256     g_return_val_if_fail (QofDateInit, NULL);
00257     d = g_hash_table_lookup (DateFormatTable, GINT_TO_POINTER (format));
00258     if (!d)
00259     {
00260         PERR (" unknown format: '%d'", format);
00261         return NULL;
00262     }
00263     return d->name;
00264 }

void qof_date_free QofDate date  ) 
 

free a QofDate

Definition at line 605 of file qofdate.c.

00606 {
00607     g_return_if_fail (date);
00608     g_free (date);
00609     date = NULL;
00610 }

QofDate* qof_date_from_gdate const GDate *  gd  ) 
 

Create a QofDate from a GDate.

A GDate is always within the range of a QofDate.

Parameters:
gd A valid GDate.
Returns:
NULL on error, otherwise a newly allocated, valid, QofDate.

Definition at line 747 of file qofdate.c.

00748 {
00749     QofDate * qd;
00750 
00751     g_return_val_if_fail (g_date_valid (date), NULL);
00752     qd = qof_date_new ();
00753     qd->qd_year = g_date_get_year (date);
00754     qd->qd_mon  = g_date_get_month (date);
00755     qd->qd_mday = g_date_get_day (date);
00756     qd = date_normalise (qd);
00757     return qd;
00758 }

QofDate* qof_date_from_qtime const QofTime qt  ) 
 

Return a QofDate in UTC from a QofTime.

Definition at line 847 of file qofdate.c.

00848 {
00849     QofDate *qd;
00850     gint leap_extra_secs;
00851 
00852     /* may not want to create a new time or date - it
00853     complicates memory management. */
00854     g_return_val_if_fail (qt, NULL);
00855     g_return_val_if_fail (qof_time_is_valid (qt), NULL);
00856     qd = qof_date_new ();
00857     leap_extra_secs = 0;
00858     tzset();
00859     leap_extra_secs = extract_interval (qt);
00860     qof_date_offset (qt, leap_extra_secs, qd);
00861     qd->qd_nanosecs = qof_time_get_nanosecs (qt);
00862     qd->qd_is_dst = 0;
00863     qd->qd_zone = "GMT";
00864     qd->qd_gmt_off = 0L;
00865     if (!qof_date_valid(qd))
00866         return NULL;
00867     return qd;
00868 }

QofDate* qof_date_from_struct_tm const struct tm *  stm  ) 
 

Convert a struct tm to a QofDate.

Parameters:
stm A pointer to a valid struct tm.
Returns:
Newly allocated QofDate or NULL if tm is NULL.

Definition at line 676 of file qofdate.c.

00677 {
00678     QofDate *d;
00679 
00680     g_return_val_if_fail (stm, NULL);
00681     d = g_new0 (QofDate, 1);
00682     d->qd_sec  = stm->tm_sec;
00683     d->qd_min  = stm->tm_min;
00684     d->qd_hour = stm->tm_hour;
00685     d->qd_mday = stm->tm_mday;
00686     d->qd_mon  = stm->tm_mon + 1;
00687     d->qd_year = stm->tm_year + 1900;
00688     d->qd_wday = stm->tm_wday;
00689     d->qd_yday = stm->tm_yday;
00690     d->qd_is_dst = stm->tm_isdst;
00691     d->qd_gmt_off = stm->tm_gmtoff;
00692     d->qd_zone = stm->tm_zone;
00693     d->qd_valid = TRUE;
00694     d = date_normalise(d);
00695     return d;
00696 }

QofDate* qof_date_get_current void   ) 
 

create a new QofDate for the current date and time.

Definition at line 579 of file qofdate.c.

00580 {
00581     QofTime *qt;
00582     QofDate *qd;
00583 
00584     qt = qof_time_get_current ();
00585     qd = qof_date_from_qtime (qt);
00586     qof_time_free (qt);
00587     return qd;
00588 }

guint8 qof_date_get_mday gint  month,
gint64  year
 

full range version of g_date_get_days_in_month

Parameters:
month Any valid QofDate qd_mon, 1 to 12.
year Any valid QofDate qd_year.
Returns:
0 on error, otherwise the number of days in the specified month, taking leap years into account.

Definition at line 181 of file qofdate.c.

00182 {
00183     g_return_val_if_fail (month !=  0, 0);
00184     g_return_val_if_fail (month <= 12, 0);
00185     g_return_val_if_fail (month >=  1, 0);
00186     g_return_val_if_fail (year  !=  0, 0);
00187     return days_in_months[qof_date_isleap (year)][month];
00188 }

guint16 qof_date_get_yday gint  mday,
gint  month,
gint64  year
 

full range version of g_date_get_day_of_year

Parameters:
mday Any valid QofDate qd_mday, 1 to 31.
month Any valid QofDate qd_mon, 1 to 12.
year Any valid QofDate qd_year.
Returns:
0 if error, otherwise the day of the year, where Jan 1 is 1, the first day of the year.

Definition at line 165 of file qofdate.c.

00166 {
00167     guint8 leap;
00168 
00169     g_return_val_if_fail (mday  != 0, 0);
00170     g_return_val_if_fail (month != 0, 0);
00171     g_return_val_if_fail (month <= 12, 0);
00172     g_return_val_if_fail (month >= 1, 0);
00173     g_return_val_if_fail (year  != 0, 0);
00174     leap = qof_date_isleap (year);
00175     g_return_val_if_fail (mday <= 
00176         qof_date_get_mday (month, year), 0);
00177     return days_in_year[leap][month] + mday;
00178 }

gboolean qof_date_is_last_mday const QofDate qd  ) 
 

Checks if QofDate the last day of the month.

Parameters:
qd A valid QofDate.
Returns:
TRUE if qd_mday is the last day of qd_mon in qd_year, otherwise (or on error), FALSE.

Definition at line 191 of file qofdate.c.

00192 {
00193     g_return_val_if_fail (qd, FALSE);
00194     g_return_val_if_fail (qd->qd_valid, FALSE);
00195     return (qd->qd_mday == 
00196         qof_date_get_mday (qd->qd_mon, qd->qd_year));
00197 }

QofDate* qof_date_new void   ) 
 

create a new, empty, QofDate

Definition at line 570 of file qofdate.c.

00571 {
00572     QofDate *d;
00573 
00574     d = g_new0 (QofDate, 1);
00575     return d;
00576 }

QofDate* qof_date_new_dmy gint  day,
gint  month,
gint64  year
 

create a new QofDate from basic calendar data.

Definition at line 591 of file qofdate.c.

00592 {
00593     QofDate *qd;
00594 
00595     qd = g_new0 (QofDate, 1);
00596     qd->qd_mday = day;
00597     qd->qd_mon  = month;
00598     qd->qd_year = year;
00599     if(!qof_date_valid (qd))
00600         return NULL;
00601     return qd;
00602 }

QofDate* qof_date_parse const gchar *  str,
QofDateFormat  df
 

Convert a timestamp to a QofTime.

Safe for all dates within the range of QofDate.

Parameters:
str a timestamp created with one of the registered QofDateFormat formats.
df The registered QofDateFormat that produced the string.
Returns:
a newly allocated, valid, QofDate or NULL on error.

Definition at line 522 of file qofdate.c.

00523 {
00524     const gchar *format;
00525     QofDateError error;
00526     QofDate *date;
00527     gchar *check;
00528 
00529     check = NULL;
00530     error = ERR_NO_ERROR;
00531     date = qof_date_new ();
00532     format = qof_date_format_get_format (df);
00533     check = strptime_internal (str, format, date, &error);
00534     if (error != ERR_NO_ERROR)
00535     {
00536         qof_date_free (date);
00537         return NULL;
00538     }
00539     date = date_normalise (date);
00540     return date;
00541 }

gchar* qof_date_print const QofDate date,
QofDateFormat  df
 

Convert a QofDate to a timestamp according to the specified date format.

Unlike qof_time_stamp_now, any supported QofDate can be converted in any registered QofDateFormat.

Parameters:
date A valid QofDate.
df a registered QofDateFormat to use to create the string.
Returns:
NULL on error, otherwise a string which should be freed when no longer needed.

Definition at line 544 of file qofdate.c.

00545 {
00546     size_t result;
00547     gchar temp[MAX_DATE_BUFFER];
00548     QofDateEntry *d;
00549 
00550     g_return_val_if_fail (QofDateInit, NULL);
00551     g_return_val_if_fail (date, NULL);
00552     g_return_val_if_fail (date->qd_valid, NULL);
00553     d = g_hash_table_lookup (DateFormatTable, 
00554         GINT_TO_POINTER (df));
00555     g_return_val_if_fail (d, NULL);
00556     temp[0] = '\1';
00557     result = strftime_case (FALSE, temp, MAX_DATE_BUFFER, 
00558         d->format, date, 1, date->qd_nanosecs);
00559     if (result == 0 && temp[0] != '\0')
00560     {
00561         PERR (" qof extended strftime failed");
00562         return NULL;
00563     }
00564     return g_strndup(temp, result);
00565 }

QofTime* qof_date_time_difference const QofDate date1,
const QofDate date2
 

Calculate the QofTime between two QofDates

Definition at line 921 of file qofdate.c.

00922 {
00923     gint64 days;
00924     QofTime *secs;
00925 
00926     secs = qof_time_new ();
00927     days = days_between (date1->qd_year, date2->qd_year);
00928     qof_time_add_secs(secs, QOF_DAYS_TO_SEC(days));
00929     if (days_between >= 0)
00930     {
00931         /* positive value, add date2 secs, subtract date1 */
00932         qof_time_add_secs(secs, -1 *
00933                 (QOF_HOUR_TO_SEC(date1->qd_hour) -
00934                 QOF_MIN_TO_SEC(date1->qd_min) -
00935                 (date1->qd_sec)));
00936         qof_time_add_secs(secs,
00937                 QOF_HOUR_TO_SEC(date2->qd_hour) +
00938                 QOF_MIN_TO_SEC(date2->qd_min) +
00939                 (date2->qd_sec));
00940         qof_time_set_nanosecs(secs, 
00941             (date1->qd_nanosecs - date2->qd_nanosecs));
00942     }
00943     if (days_between < 0)
00944     {
00945         /* negative value*/
00946         qof_time_add_secs (secs, 
00947                 QOF_HOUR_TO_SEC(date1->qd_hour) -
00948                 QOF_MIN_TO_SEC(date1->qd_min) -
00949                 (date1->qd_sec));
00950         qof_time_add_secs (secs, -1 * 
00951                 (QOF_HOUR_TO_SEC(date2->qd_hour) +
00952                 QOF_MIN_TO_SEC(date2->qd_min) +
00953                 (date2->qd_sec)));
00954         qof_time_set_nanosecs(secs, 
00955             (date2->qd_nanosecs - date1->qd_nanosecs));
00956     }
00957     return secs;
00958 }

gboolean qof_date_to_gdate const QofDate qd,
GDate *  gd
 

Convert a QofDate to a GDate.

Parameters:
qd a valid QofDate
gd a new GDate to store the converted value.
Returns:
FALSE on error, if the QofDate is out of range of a GDate or if QofDate is not valid, otherwise TRUE.

Definition at line 727 of file qofdate.c.

00728 {
00729     g_return_val_if_fail (qd, FALSE);
00730     g_return_val_if_fail (gd, FALSE);
00731     g_return_val_if_fail (qd->qd_valid, FALSE);
00732     if (qd->qd_year >= G_MAXUINT16)
00733     {
00734         PERR (" QofDate out of range of GDate");
00735         return FALSE;
00736     }
00737     if (!g_date_valid_dmy (qd->qd_mday, qd->qd_mon, qd->qd_year))
00738     {
00739         PERR (" GDate failed to allow day, month and/or year");
00740         return FALSE;
00741     }
00742     g_date_set_dmy (gd, qd->qd_mday, qd->qd_mon, qd->qd_year);
00743     return TRUE;
00744 }

QofTime* qof_date_to_qtime const QofDate qd  ) 
 

Return a valid QofTime from a valid QofDate.

Definition at line 888 of file qofdate.c.

00889 {
00890     QofTime *qt;
00891     QofTimeSecs c;
00892 
00893     g_return_val_if_fail (qd, NULL);
00894     g_return_val_if_fail (qd->qd_valid, NULL);
00895     c = 0;
00896     qt = NULL;
00897     if (qd->qd_year < 1970)
00898     {
00899         c = qd->qd_sec;
00900         c += QOF_MIN_TO_SEC(qd->qd_min);
00901         c += QOF_HOUR_TO_SEC(qd->qd_hour);
00902         c += QOF_DAYS_TO_SEC(qd->qd_yday);
00903         c -= QOF_DAYS_TO_SEC(days_between (1970, qd->qd_year));
00904         c -= qd->qd_gmt_off;
00905         qt = qof_time_set (c, qd->qd_nanosecs);
00906     }
00907     if (qd->qd_year >= 1970)
00908     {
00909         c = qd->qd_sec;
00910         c += QOF_MIN_TO_SEC(qd->qd_min);
00911         c += QOF_HOUR_TO_SEC(qd->qd_hour);
00912         c += QOF_DAYS_TO_SEC(qd->qd_yday);
00913         c += QOF_DAYS_TO_SEC(days_between (1970, qd->qd_year));
00914         c -= qd->qd_gmt_off;
00915         qt = qof_time_set (c, qd->qd_nanosecs);
00916     }
00917     return qt;
00918 }

gboolean qof_date_to_struct_tm const QofDate qt,
struct tm *  stm,
glong *  nanosecs
 

Convert a QofDate to a struct tm.

Warning:
Check the return value - a QofDate has a larger range than a struct tm. The struct tm will be unchanged if a conversion would have been out of range.
Parameters:
qt A valid QofDate.
stm Pointer to a struct tm to store the result.
nanosecs Pointer to a glong to store the nanoseconds.
Returns:
FALSE on error or if the QofDate is invalid or out of the range of a struct tm, otherwise TRUE.

Definition at line 699 of file qofdate.c.

00701 {
00702     g_return_val_if_fail (qd, FALSE);
00703     g_return_val_if_fail (stm, FALSE);
00704     g_return_val_if_fail (qd->qd_valid, FALSE);
00705     if ((qd->qd_year > G_MAXINT) || (qd->qd_year < 1900))
00706     {
00707         PERR (" date too large for struct tm");
00708         return FALSE;
00709     }
00710     stm->tm_sec  = qd->qd_sec;
00711     stm->tm_min  = qd->qd_min;
00712     stm->tm_hour = qd->qd_hour;
00713     stm->tm_mday = qd->qd_mday;
00714     stm->tm_mon  = qd->qd_mon - 1;
00715     stm->tm_year = qd->qd_year - 1900;
00716     stm->tm_wday = qd->qd_wday;
00717     stm->tm_yday = qd->qd_yday;
00718     stm->tm_isdst = qd->qd_is_dst;
00719     stm->tm_gmtoff = qd->qd_gmt_off;
00720     stm->tm_zone = qd->qd_zone;
00721     if (nanosecs != NULL)
00722         *nanosecs = qd->qd_nanosecs;
00723     return TRUE;
00724 }

gboolean qof_date_valid QofDate date  ) 
 

Validate a QofDate.

If the QofDate is already valid, just returns TRUE. If the QofDate is not valid but can be normalised, the QofDate is normalised and the function returns TRUE. If the QofDate cannot be normalised, returns FALSE.

Year Zero does not exist in the Christian Era, the Gregorian calendar or the Julian calendar. A year zero does exist in ISO 8601:2004 and in the astronomical year numbering with a defined year zero equal to 1 BC, as well as in some Buddhist and Hindu lunar calendars.

In QofDate, 1BC is immediately followed by 1AD and months are numbered from 1 to 12, not from zero.

Normalising a QofDate tries to use sensible defaults:

  • if qd_mon == 0, validating sets qd_mon to 1 (January)
  • if qd_year == 0, validating sets qd_year to -1 (1BC).
  • if qd_mday == 0, validating sets qd_mday to 1.

Definition at line 613 of file qofdate.c.

00614 {
00615     g_return_val_if_fail (date, FALSE);
00616     date = date_normalise (date);
00617     if (date->qd_valid == FALSE)
00618     {
00619         PERR (" unknown QofDate error");
00620         return FALSE;
00621     }
00622     return TRUE;
00623 }


Generated on Fri Sep 1 15:35:59 2006 for QOF by  doxygen 1.4.6