diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index 1dcf5ae3bf..f3c9e15705 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -646,7 +646,7 @@ xaccTransSetDateStr (Transaction *trans, char *str) { Date d; - sscandate (str, &d, DATE_FULL); + scanDate(str, &(d.day), &(d.month), &(d.year)); xaccTransSetDate (trans, d.day, d.month, d.year); } @@ -758,12 +758,8 @@ xaccTransGetDate (Transaction *trans) char * xaccTransGetDateStr (Transaction *trans) { - - char buf [100]; - sprintf( buf, "%2d/%2d/%02d", - trans->date.month, - trans->date.day, - (trans->date.year%100) ); + char buf [MAX_DATE_LENGTH]; + printDate(buf, trans->date.day, trans->date.month, trans->date.year%100); return strdup (buf); } diff --git a/src/engine/date.c b/src/engine/date.c index 7ddbbdcec4..9af87f7f66 100644 --- a/src/engine/date.c +++ b/src/engine/date.c @@ -46,15 +46,161 @@ char days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; static int been_here = 0; +DateFormat dateFormat = DATE_FORMAT_US; + /********************************************************************\ \********************************************************************/ -void -sprtDate (char * buff, int day, int month, int year) + +/** + * printDate + * 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. + * day - day of the month as 1 ... 31 + * month - month of the year as 1 ... 12 + * year - year (4-digit) + * + * Return: nothing + * + * Globals: global dateFormat value + */ +void printDate (char * buff, int day, int month, int year) { - sprintf (buff, "%2d/%2d/%4d", month, day, year); + switch(dateFormat) + { + case DATE_FORMAT_UK: + sprintf (buff, "%2d/%2d/%4d", day, month, year); + break; + case DATE_FORMAT_CE: + sprintf (buff, "%2d.%2d.%4d", day, month, year); + break; + case DATE_FORMAT_ISO: + sprintf (buff, "%04d-%02d-%02d", year, month, day); + break; + case DATE_FORMAT_US: + default: + sprintf (buff, "%2d/%2d/%4d", month, day, year); + break; + } } + +/** + * scanDate + * 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: 0 if conversion was successful, 1 otherwise + * + * Globals: global dateFormat value + */ +int scanDate(const char *buff, int *day, int *month, int *year) +{ + char *dupe, *tmp, *first_field, *second_field, *third_field; + int iday, imonth, iyear; + time_t secs; + struct tm *now; + + dupe = strdup (buff); + tmp = dupe; + first_field = 0x0; + second_field = 0x0; + third_field = 0x0; + + /* use strtok to find delimiters */ + if (tmp) { + first_field = strtok (tmp, ".,-+/\\()"); + if (first_field) { + second_field = strtok (NULL, ".,-+/\\()"); + if (second_field) { + third_field = strtok (NULL, ".,-+/\\()"); + } + } + } + + /* if any fields appear blank, use today's date */ + time (&secs); + now = localtime (&secs); + iday = now->tm_mday; + imonth = now->tm_mon+1; + iyear = now->tm_year+1900; + + /* get numeric values */ + switch(dateFormat) + { + case DATE_FORMAT_UK: + case DATE_FORMAT_CE: + if (first_field) iday = atoi (first_field); + if (second_field) imonth = atoi (second_field); + if (third_field) iyear = atoi (third_field); + break; + case DATE_FORMAT_ISO: + if (first_field) iyear = atoi (first_field); + if (second_field) imonth = atoi (second_field); + if (third_field) iday = atoi (third_field); + break; + case DATE_FORMAT_US: + default: + if (first_field) imonth = atoi (first_field); + if (second_field) iday = atoi (second_field); + if (third_field) iyear = atoi (third_field); + break; + } + + free (dupe); + + /* if the year entered is smaller than 100, assume we mean the current + century (and are not revising some roman emperor's books) */ + if(iyear<100) + iyear += ((int) ((now->tm_year+1900)/100)) * 100; + + *year=iyear; + *month=imonth; + *day=iday; + + return; +} + +/** + * dateSeparator + * Return the field separator for the current date format + * + * Args: none + * + * Return: date character + * + * Globals: global dateFormat value + */ +char dateSeparator() +{ + char separator; + switch(dateFormat) + { + case DATE_FORMAT_CE: + separator='.'; + break; + case DATE_FORMAT_ISO: + separator='-'; + break; + case DATE_FORMAT_US: + case DATE_FORMAT_UK: + default: + separator='/'; + break; + } + return separator; +} + + + /********************************************************************\ * adjustDay * * adds adj to the current day of the month... the resulting day * @@ -240,41 +386,19 @@ datecmp( Date *date1, Date *date2 ) } } -/********************************************************************\ - * sscandate * - * parses a date from a given string * - * * - * Args: in_string -- the string to parse * - * date -- the date into which the parsed date is placed * - * flag -- indicates whether to parse the whole of the * - * or a portion. Valid values are: * - DATE_SHORT, DATE_YEAR and DATE_FULL * - * Return: number of characters read from string * -\********************************************************************/ -int -sscandate( const char *in_string, Date *date, int flags ) -{ - int *a,*b,*c; /* pointers to address of day, month and year vars */ - int ret; - -#ifdef UK_DATES - a=&date->day; b=&date->month; c=&date->year; -#else - a=&date->month; b=&date->day; c=&date->year; -#endif - - switch (flags) - { - case DATE_SHORT: - ret=sscanf( in_string, "%d/%d", a, b ); break; - case DATE_YEAR: - ret=sscanf( in_string, "%d", c ); break; - case DATE_FULL: - ret=sscanf( in_string, "%d/%d/%d", a, b, c); break; - } - return ret; -} /********************** END OF FILE *********************************\ \********************************************************************/ + + +/* + Local Variables: + tab-width: 2 + indent-tabs-mode: nil + mode: c-mode + c-indentation-style: gnu + eval: (c-set-offset 'block-open '-) + End: +*/ + diff --git a/src/engine/date.h b/src/engine/date.h index 9ca21525e7..bdcfafa233 100644 --- a/src/engine/date.h +++ b/src/engine/date.h @@ -97,8 +97,21 @@ typedef struct _date { int day; } Date; +typedef enum +{ + DATE_FORMAT_US, /* United states: mm/dd/yyyy */ + DATE_FORMAT_UK, /* Britain: dd/mm/yyyy */ + DATE_FORMAT_CE, /* Continental Europe: dd.mm.yyyy */ + DATE_FORMAT_ISO /* ISO: yyyy-mm-dd */ +} DateFormat; + +/* the maximum length of a string created by sprtDate() */ +#define MAX_DATE_LENGTH 11 + /** PROTOTYPES ******************************************************/ -void sprtDate (char * buff, int day, int month, int year); +void printDate (char * buff, int day, int month, int year); +int scanDate (const char *buff, int *day, int *monty, int *year); +char dateSeparator(void); void adjustDay( Date *date, int adj ); void adjustMonth( Date *date, int adj ); @@ -109,13 +122,11 @@ Date* todaysDate( Date *date ); int daysInMonth( int month , int year ); int datecmp( Date *date1, Date *date2 ); -#define DATE_SHORT 0 -#define DATE_YEAR 1 -#define DATE_FULL 2 - int sscandate( const char *in_string, Date *date, int flags); /** GLOBALS *********************************************************/ +extern DateFormat dateFormat; + #endif /* __XACC_DATE_H__ */ diff --git a/src/register/datecell.c b/src/register/datecell.c index 81371c9003..574040a0b3 100644 --- a/src/register/datecell.c +++ b/src/register/datecell.c @@ -46,74 +46,16 @@ static void setDateCellValue (BasicCell *, const char *); (cell)->value = strdup (str); \ } -#define DATE_SEP '/' - /* ================================================ */ -static void -prtDate (char * buff, int day, int month, int year) -{ - sprintf (buff, "%2d/%2d/%4d", month, day, year); -} - -/* ================================================ */ static void xaccParseDate (struct tm *parsed, const char * datestr) { - char *dupe, *tmp, *first_field, *second_field, *third_field; + int iday, imonth, iyear; - time_t secs; - struct tm *now; - dupe = strdup (datestr); - tmp = dupe; - first_field = 0x0; - second_field = 0x0; - third_field = 0x0; - - /* use strtok to find delimiters */ - if (tmp) { - first_field = strtok (tmp, ".,-+/\\()"); - if (first_field) { - second_field = strtok (NULL, ".,-+/\\()"); - if (second_field) { - third_field = strtok (NULL, ".,-+/\\()"); - } - } - } - - /* if any fields appear blank, use today's date */ - time (&secs); - now = localtime (&secs); - iday = now->tm_mday; - imonth = now->tm_mon+1; - iyear = now->tm_year+1900; - -#ifdef _PARSE_DATE_AS_DD_MM_YY - /* get numeric values */ - if (first_field) iday = atoi (first_field); - if (second_field) imonth = atoi (second_field); - if (third_field) iyear = atoi (third_field); -#endif /* _PARSE_DATE_AS_DD_MM_YY */ - -#define _PARSE_DATE_AS_MM_DD_YY -#ifdef _PARSE_DATE_AS_MM_DD_YY - /* get numeric values */ - if (first_field) imonth = atoi (first_field); - if (second_field) iday = atoi (second_field); - if (third_field) iyear = atoi (third_field); -#endif /* _PARSE_DATE_AS_MM_DD_YY */ - - /* check to see if day & month are reversed */ - /* only works for some dates */ - if (12 < imonth) { - int itmp = imonth; - imonth = iday; - iday = itmp; - } - - free (dupe); + scanDate(datestr, &iday, &imonth, &iyear); if (parsed) { parsed->tm_mday = iday; @@ -213,7 +155,9 @@ DateMV (BasicCell *_cell, if (isdigit (change[0])) return newval; /* accept the separator character */ - if (DATE_SEP == change[0]) return newval; + /* Note that the separator of '-' (for DATE_FORMAT_ISO) takes precedence + over the accelerator below! */ + if (dateSeparator() == change[0]) return newval; /* otherwise, maybe its an accelerator key. */ date = &(cell->date); @@ -295,7 +239,7 @@ DateMV (BasicCell *_cell, xaccValidateDate (date, 0); } - prtDate (buff, date->tm_mday, date->tm_mon+1, date->tm_year+1900); + printDate (buff, date->tm_mday, date->tm_mon+1, date->tm_year+1900); if (cell->cell.value) free (cell->cell.value); cell->cell.value = strdup (buff); @@ -318,7 +262,7 @@ DateLeave (BasicCell *_cell, const char * curr) * what date that cell thinks it has. */ xaccParseDate (&(cell->date), curr); - prtDate (buff, cell->date.tm_mday, + printDate (buff, cell->date.tm_mday, cell->date.tm_mon+1, cell->date.tm_year+1900); @@ -355,7 +299,7 @@ xaccInitDateCell (DateCell *cell) time (&secs); now = localtime (&secs); cell->date = *now; - prtDate (buff, now->tm_mday, now->tm_mon+1, now->tm_year+1900); + printDate (buff, now->tm_mday, now->tm_mon+1, now->tm_year+1900); SET (&(cell->cell), buff); @@ -393,7 +337,7 @@ xaccSetDateCellValue (DateCell *cell, int day, int mon, int year) cell->date.tm_mon = dada.tm_mon; cell->date.tm_year = dada.tm_year; - prtDate (buff, dada.tm_mday, dada.tm_mon+1, dada.tm_year+1900); + printDate (buff, dada.tm_mday, dada.tm_mon+1, dada.tm_year+1900); if (cell->cell.value) free (cell->cell.value); cell->cell.value = strdup (buff); @@ -409,7 +353,7 @@ setDateCellValue (BasicCell *_cell, const char *str) xaccParseDate (&(cell->date), str); - prtDate (buff, cell->date.tm_mday, + printDate (buff, cell->date.tm_mday, cell->date.tm_mon+1, cell->date.tm_year+1900);