Implement gnc_timegm directly without mktime.

Calculate the seconds since the start of the UNIX epoch directly without
the help of mktime. This also works on Windows. Systems with timegm are
unaffected.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15472 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Andreas Köhler 2007-01-31 00:05:23 +00:00
parent a23e280d8d
commit f81aa515fd

View File

@ -381,35 +381,36 @@ simple_chars_only_parser_new(sixtp_end_handler end_handler)
#ifdef HAVE_TIMEGM
# define gnc_timegm timegm
#else
#else /* !HAVE_TIMEGM */
/* This code originates from GLib 2.12, gtimer.c and works until the year 2100
* or the system-dependent maximal date that can be represented by a time_t,
* whatever comes first. The old implementation called mktime after setting
* the environment variable TZ to UTC. It did not work on Windows, at least.
*/
static const gint days_before[] = {
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
};
static time_t
gnc_timegm (struct tm *tm)
{
time_t result;
char *old_tz;
time_t retval;
if (tm->tm_mon < 0 || tm->tm_mon > 11)
return (time_t) -1;
old_tz = g_strdup(g_getenv ("TZ"));
/* FIXME: there's no way to report this error to the caller. */
if (!g_setenv("TZ", "UTC", TRUE))
PERR ("couldn't switch the TZ.");
result = mktime (tm);
if(old_tz)
{
/* FIXME: there's no way to report this error to the caller. */
if (!g_setenv("TZ", old_tz, TRUE))
PERR ("couldn't switch the TZ back.");
g_free(old_tz);
retval = (tm->tm_year - 70) * 365;
retval += (tm->tm_year - 68) / 4;
retval += days_before[tm->tm_mon] + tm->tm_mday - 1;
if (tm->tm_year % 4 == 0 && tm->tm_mon < 2)
retval -= 1;
retval = ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 + tm->tm_sec;
return retval;
}
else
{
/* FIXME: there's no way to report this error to the caller. */
g_unsetenv("TZ");
if(errno != 0)
PERR ("couldn't restore the TZ to undefined.");
}
return result;
}
#endif
#endif /* HAVE_TIMEGM */
/****************************************************************************/