datetime: Fix leap year check

Remove a FIXME and an approximation when computing the seconds from
the Unix epoch.
This commit is contained in:
Emmanuele Bassi 2010-08-25 12:30:09 +01:00
parent 2952e908e4
commit 5e65ed4e44

View File

@ -86,7 +86,7 @@
#define USEC_PER_MILLISECOND (G_GINT64_CONSTANT (1000))
#define USEC_PER_DAY (G_GINT64_CONSTANT (86400000000))
#define GREGORIAN_LEAP(y) (((y % 4) == 0) && (!(((y % 100) == 0) && ((y % 400) != 0))))
#define GREGORIAN_LEAP(y) ((((y) % 4) == 0) && (!((((y) % 100) == 0) && (((y) % 400) != 0))))
#define JULIAN_YEAR(d) ((d)->julian / 365.25)
#define DAYS_PER_PERIOD (G_GINT64_CONSTANT (2914695))
@ -513,29 +513,36 @@ g_time_zone_new_from_epoch (const gchar *tzname,
#define SECS_PER_JULIAN (DAYS_PER_PERIOD * SECS_PER_DAY)
static gint64
g_date_time_secs_offset (GDateTime * dt)
g_date_time_secs_offset (const GDateTime * dt)
{
gint64 secs;
gint d, y, h, m, s;
gint leaps;
gint i, leaps;
y = g_date_time_get_year (dt) - 1970;
y = g_date_time_get_year (dt);
d = g_date_time_get_day_of_year (dt);
h = g_date_time_get_hour (dt);
m = g_date_time_get_minute (dt);
s = g_date_time_get_second (dt);
/* FIXME this is an approximation */
leaps = y / 4;
leaps = GREGORIAN_LEAP (y) ? 1 : 0;
for (i = 1970; i < y; i++)
{
if (GREGORIAN_LEAP (i))
leaps += 1;
}
secs = 0;
secs += y * SECS_PER_YEAR;
secs += (y - 1970) * SECS_PER_YEAR;
secs += d * SECS_PER_DAY;
secs += leaps * SECS_PER_DAY;
secs += (leaps - 1) * SECS_PER_DAY;
secs += h * SECS_PER_HOUR;
secs += m * SECS_PER_MINUTE;
secs += s;
if (dt->tz != NULL)
secs -= dt->tz->offset;
return secs;
}