mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Henning's date internationalization code
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@751 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
83ea1b3ed7
commit
a3c9ac6853
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
*/
|
||||
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user