Clean-up/tweaking of GDateTime and GTimeZone

This commit is contained in:
Ryan Lortie 2010-09-16 04:44:59 -04:00
parent 909289c763
commit 6b0e31ce48
10 changed files with 2595 additions and 2114 deletions

View File

@ -76,6 +76,7 @@ synchronize their operation.
<xi:include href="xml/checksum.xml" /> <xi:include href="xml/checksum.xml" />
<xi:include href="xml/i18n.xml" /> <xi:include href="xml/i18n.xml" />
<xi:include href="xml/date.xml" /> <xi:include href="xml/date.xml" />
<xi:include href="xml/timezone.xml" />
<xi:include href="xml/date-time.xml" /> <xi:include href="xml/date-time.xml" />
<xi:include href="xml/random_numbers.xml" /> <xi:include href="xml/random_numbers.xml" />
<xi:include href="xml/hooks.xml" /> <xi:include href="xml/hooks.xml" />

View File

@ -1407,66 +1407,119 @@ g_date_monday_weeks_in_year
g_date_sunday_weeks_in_year g_date_sunday_weeks_in_year
</SECTION> </SECTION>
<SECTION>
<FILE>timezone</FILE>
<SUBSECTION>
GTimeZone
g_time_zone_unref
g_time_zone_ref
<SUBSECTION>
g_time_zone_new
g_time_zone_new_local
g_time_zone_new_utc
<SUBSECTION>
GTimeType
g_time_zone_find_interval
g_time_zone_adjust_time
<SUBSECTION>
g_time_zone_get_abbreviation
g_time_zone_get_offset
g_time_zone_is_dst
</SECTION>
<SECTION> <SECTION>
<FILE>date-time</FILE> <FILE>date-time</FILE>
GTimeSpan
G_TIME_SPAN_DAY G_TIME_SPAN_DAY
G_TIME_SPAN_HOUR G_TIME_SPAN_HOUR
G_TIME_SPAN_MINUTE G_TIME_SPAN_MINUTE
G_TIME_SPAN_SECOND G_TIME_SPAN_SECOND
G_TIME_SPAN_MILLISECONT G_TIME_SPAN_MILLISECOND
GTimeSpan
<SUBSECTION> <SUBSECTION>
GDateTime GDateTime
g_date_time_new_full
g_date_time_new_from_date
g_date_time_new_from_epoch
g_date_time_new_from_timeval
g_date_time_new_now
g_date_time_new_utc_now
g_date_time_new_today
g_date_time_ref
g_date_time_unref g_date_time_unref
g_date_time_ref
<SUBSECTION>
g_date_time_new_now
g_date_time_new_now_local
g_date_time_new_now_utc
<SUBSECTION>
g_date_time_new_from_unix_local
g_date_time_new_from_unix_utc
<SUBSECTION>
g_date_time_new_from_timeval_local
g_date_time_new_from_timeval_utc
<SUBSECTION>
g_date_time_new
g_date_time_new_local
g_date_time_new_utc
<SUBSECTION> <SUBSECTION>
g_date_time_add g_date_time_add
<SUBSECTION>
g_date_time_add_years g_date_time_add_years
g_date_time_add_months g_date_time_add_months
g_date_time_add_weeks g_date_time_add_weeks
g_date_time_add_days g_date_time_add_days
<SUBSECTION>
g_date_time_add_hours g_date_time_add_hours
g_date_time_add_minutes g_date_time_add_minutes
g_date_time_add_seconds g_date_time_add_seconds
g_date_time_add_milliseconds
<SUBSECTION>
g_date_time_add_full g_date_time_add_full
<SUBSECTION> <SUBSECTION>
g_date_time_difference
g_date_time_compare g_date_time_compare
g_date_time_equal g_date_time_difference
g_date_time_hash g_date_time_hash
g_date_time_equal
<SUBSECTION>
g_date_time_get_ymd
<SUBSECTION> <SUBSECTION>
g_date_time_get_dmy
g_date_time_get_year g_date_time_get_year
g_date_time_get_month g_date_time_get_month
g_date_time_get_week_of_year
g_date_time_get_day_of_month g_date_time_get_day_of_month
<SUBSECTION>
g_date_time_get_week_of_year
g_date_time_get_day_of_week g_date_time_get_day_of_week
<SUBSECTION>
g_date_time_get_day_of_year g_date_time_get_day_of_year
<SUBSECTION>
g_date_time_get_hour g_date_time_get_hour
g_date_time_get_minute g_date_time_get_minute
g_date_time_get_second g_date_time_get_second
g_date_time_get_millisecond
g_date_time_get_microsecond g_date_time_get_microsecond
g_date_time_get_julian g_date_time_get_seconds
g_date_time_get_utc_offset
g_date_time_get_timezone_name
g_date_time_is_daylight_savings
g_date_time_is_leap_year
<SUBSECTION> <SUBSECTION>
g_date_time_day g_date_time_to_unix
g_date_time_to_epoch
g_date_time_to_local
g_date_time_to_timeval g_date_time_to_timeval
<SUBSECTION>
g_date_time_get_utc_offset
g_date_time_get_timezone_abbreviation
g_date_time_is_daylight_savings
<SUBSECTION>
g_date_time_to_timezone
g_date_time_to_local
g_date_time_to_utc g_date_time_to_utc
g_date_time_printf
<SUBSECTION>
g_date_time_format
</SECTION> </SECTION>
<SECTION> <SECTION>

View File

@ -177,6 +177,7 @@ libglib_2_0_la_SOURCES = \
gthreadprivate.h \ gthreadprivate.h \
gthreadpool.c \ gthreadpool.c \
gtimer.c \ gtimer.c \
gtimezone.c \
gtree.c \ gtree.c \
guniprop.c \ guniprop.c \
gutf8.c \ gutf8.c \
@ -276,6 +277,7 @@ glibsubinclude_HEADERS = \
gthread.h \ gthread.h \
gthreadpool.h \ gthreadpool.h \
gtimer.h \ gtimer.h \
gtimezone.h \
gtree.h \ gtree.h \
gtypes.h \ gtypes.h \
gunicode.h \ gunicode.h \

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,26 @@
/* gdatetime.h /*
*
* Copyright (C) 2009-2010 Christian Hergert <chris@dronelabs.com> * Copyright (C) 2009-2010 Christian Hergert <chris@dronelabs.com>
* Copyright © 2010 Codethink Limited
* *
* This is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or modify
* modify it under the terms of the GNU Lesser General Public * it under the terms of the GNU Lesser General Public License as
* License as published by the Free Software Foundation; either * published by the Free Software Foundation; either version 2.1 of the
* version 2.1 of the License, or (at your option) any later version. * licence, or (at your option) any later version.
* *
* This is distributed in the hope that it will be useful, * This is distributed in the hope that it will be useful, but WITHOUT
* but WITHOUT ANY WARRANTY; without even the implied warranty of * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* Lesser General Public License for more details. * License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA.
*
* Authors: Christian Hergert <chris@dronelabs.com>
* Thiago Santos <thiago.sousa.santos@collabora.co.uk>
* Emmanuele Bassi <ebassi@linux.intel.com>
* Ryan Lortie <desrt@desrt.ca>
*/ */
#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) #if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
@ -24,8 +30,7 @@
#ifndef __G_DATE_TIME_H__ #ifndef __G_DATE_TIME_H__
#define __G_DATE_TIME_H__ #define __G_DATE_TIME_H__
#include <time.h> #include <glib/gtimezone.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -83,16 +88,6 @@ G_BEGIN_DECLS
*/ */
typedef gint64 GTimeSpan; typedef gint64 GTimeSpan;
/**
* GTimeZone:
*
* <structname>GTimeZone</structname> is an opaque structure whose members
* cannot be accessed directly.
*
* Since: 2.26
*/
typedef struct _GTimeZone GTimeZone;
/** /**
* GDateTime: * GDateTime:
* *
@ -103,109 +98,109 @@ typedef struct _GTimeZone GTimeZone;
*/ */
typedef struct _GDateTime GDateTime; typedef struct _GDateTime GDateTime;
GDateTime * g_date_time_new_now (void); void g_date_time_unref (GDateTime *datetime);
GDateTime * g_date_time_new_today (void); GDateTime * g_date_time_ref (GDateTime *datetime);
GDateTime * g_date_time_new_utc_now (void);
GDateTime * g_date_time_new_from_date (gint year, GDateTime * g_date_time_new_now (GTimeZone *tz);
gint month, GDateTime * g_date_time_new_now_local (void);
gint day); GDateTime * g_date_time_new_now_utc (void);
GDateTime * g_date_time_new_from_epoch (gint64 secs);
GDateTime * g_date_time_new_from_timeval (GTimeVal *tv); GDateTime * g_date_time_new_from_unix_local (gint64 t);
GDateTime * g_date_time_new_full (gint year, GDateTime * g_date_time_new_from_unix_utc (gint64 t);
GDateTime * g_date_time_new_from_timeval_local (const GTimeVal *tv);
GDateTime * g_date_time_new_from_timeval_utc (const GTimeVal *tv);
GDateTime * g_date_time_new (GTimeZone *tz,
gint year,
gint month, gint month,
gint day, gint day,
gint hour, gint hour,
gint minute, gint minute,
gdouble second, gdouble seconds);
const GTimeZone *time_zone); GDateTime * g_date_time_new_local (gint year,
gint month,
gint day,
gint hour,
gint minute,
gdouble seconds);
GDateTime * g_date_time_new_utc (gint year,
gint month,
gint day,
gint hour,
gint minute,
gdouble seconds);
GDateTime * g_date_time_ref (GDateTime *datetime); GDateTime * g_date_time_add (GDateTime *datetime,
void g_date_time_unref (GDateTime *datetime);
GDateTime * g_date_time_add (const GDateTime *datetime,
GTimeSpan timespan); GTimeSpan timespan);
GDateTime * g_date_time_add_days (const GDateTime *datetime,
gint days); GDateTime * g_date_time_add_years (GDateTime *datetime,
GDateTime * g_date_time_add_hours (const GDateTime *datetime,
gint hours);
GDateTime * g_date_time_add_milliseconds (const GDateTime *datetime,
gint milliseconds);
GDateTime * g_date_time_add_minutes (const GDateTime *datetime,
gint minutes);
GDateTime * g_date_time_add_months (const GDateTime *datetime,
gint months);
GDateTime * g_date_time_add_seconds (const GDateTime *datetime,
gint seconds);
GDateTime * g_date_time_add_weeks (const GDateTime *datetime,
gint weeks);
GDateTime * g_date_time_add_years (const GDateTime *datetime,
gint years); gint years);
GDateTime * g_date_time_add_full (const GDateTime *datetime, GDateTime * g_date_time_add_months (GDateTime *datetime,
gint months);
GDateTime * g_date_time_add_weeks (GDateTime *datetime,
gint weeks);
GDateTime * g_date_time_add_days (GDateTime *datetime,
gint days);
GDateTime * g_date_time_add_hours (GDateTime *datetime,
gint hours);
GDateTime * g_date_time_add_minutes (GDateTime *datetime,
gint minutes);
GDateTime * g_date_time_add_seconds (GDateTime *datetime,
gdouble seconds);
GDateTime * g_date_time_add_full (GDateTime *datetime,
gint years, gint years,
gint months, gint months,
gint days, gint days,
gint hours, gint hours,
gint minutes, gint minutes,
gint seconds); gdouble seconds);
GDateTime * g_date_time_day (const GDateTime *datetime);
gint g_date_time_compare (gconstpointer dt1, gint g_date_time_compare (gconstpointer dt1,
gconstpointer dt2); gconstpointer dt2);
GTimeSpan g_date_time_difference (GDateTime *begin,
GDateTime *end);
guint g_date_time_hash (gconstpointer datetime);
gboolean g_date_time_equal (gconstpointer dt1, gboolean g_date_time_equal (gconstpointer dt1,
gconstpointer dt2); gconstpointer dt2);
guint g_date_time_hash (gconstpointer datetime);
GTimeSpan g_date_time_difference (const GDateTime *begin, void g_date_time_get_ymd (GDateTime *datetime,
const GDateTime *end); gint *year,
void g_date_time_get_julian (const GDateTime *datetime,
gint *period,
gint *julian,
gint *hour,
gint *minute,
gint *second);
gint g_date_time_get_hour (const GDateTime *datetime);
gint g_date_time_get_minute (const GDateTime *datetime);
gint g_date_time_get_second (const GDateTime *datetime);
gint g_date_time_get_millisecond (const GDateTime *datetime);
gint g_date_time_get_microsecond (const GDateTime *datetime);
gint g_date_time_get_day_of_week (const GDateTime *datetime);
gint g_date_time_get_day_of_month (const GDateTime *datetime);
gint g_date_time_get_week_of_year (const GDateTime *datetime);
gint g_date_time_get_day_of_year (const GDateTime *datetime);
gint g_date_time_get_month (const GDateTime *datetime);
gint g_date_time_get_year (const GDateTime *datetime);
void g_date_time_get_dmy (const GDateTime *datetime,
gint *day,
gint *month, gint *month,
gint *year); gint *day);
GTimeSpan g_date_time_get_utc_offset (const GDateTime *datetime); gint g_date_time_get_year (GDateTime *datetime);
G_CONST_RETURN gchar *g_date_time_get_timezone_name (const GDateTime *datetime); gint g_date_time_get_month (GDateTime *datetime);
gboolean g_date_time_is_daylight_savings (const GDateTime *datetime); gint g_date_time_get_day_of_month (GDateTime *datetime);
gboolean g_date_time_is_leap_year (const GDateTime *datetime); gint g_date_time_get_week_of_year (GDateTime *datetime);
gint g_date_time_get_day_of_week (GDateTime *datetime);
GDateTime * g_date_time_to_local (const GDateTime *datetime); gint g_date_time_get_day_of_year (GDateTime *datetime);
gint64 g_date_time_to_epoch (const GDateTime *datetime);
void g_date_time_to_timeval (const GDateTime *datetime, gint g_date_time_get_hour (GDateTime *datetime);
gint g_date_time_get_minute (GDateTime *datetime);
gint g_date_time_get_second (GDateTime *datetime);
gint g_date_time_get_microsecond (GDateTime *datetime);
gdouble g_date_time_get_seconds (GDateTime *datetime);
gint64 g_date_time_to_unix (GDateTime *datetime);
gboolean g_date_time_to_timeval (GDateTime *datetime,
GTimeVal *tv); GTimeVal *tv);
GDateTime * g_date_time_to_utc (const GDateTime *datetime);
gchar * g_date_time_format (const GDateTime *datetime,
const gchar *format) G_GNUC_MALLOC;
GTimeZone * g_time_zone_new (gint offset, GTimeSpan g_date_time_get_utc_offset (GDateTime *datetime);
gboolean is_dst); const gchar * g_date_time_get_timezone_abbreviation (GDateTime *datetime);
GTimeZone * g_time_zone_new_for_name (const gchar *name); gboolean g_date_time_is_daylight_savings (GDateTime *datetime);
GTimeZone * g_time_zone_new_utc (void);
GTimeZone * g_time_zone_new_local (void); GDateTime * g_date_time_to_timezone (GDateTime *datetime,
GTimeZone * g_time_zone_copy (const GTimeZone *time_zone); GTimeZone *tz);
void g_time_zone_free (GTimeZone *time_zone); GDateTime * g_date_time_to_local (GDateTime *datetime);
G_CONST_RETURN gchar *g_time_zone_get_name (const GTimeZone *time_zone); GDateTime * g_date_time_to_utc (GDateTime *datetime);
gint g_time_zone_get_offset (const GTimeZone *time_zone);
gboolean g_time_zone_get_is_dst (const GTimeZone *time_zone); gchar * g_date_time_format (GDateTime *datetime,
gboolean g_time_zone_is_floating (const GTimeZone *time_zone); const gchar *format) G_GNUC_MALLOC;
G_END_DECLS G_END_DECLS

View File

@ -82,6 +82,7 @@
#include <glib/gthread.h> #include <glib/gthread.h>
#include <glib/gthreadpool.h> #include <glib/gthreadpool.h>
#include <glib/gtimer.h> #include <glib/gtimer.h>
#include <glib/gtimezone.h>
#include <glib/gtree.h> #include <glib/gtree.h>
#include <glib/gtypes.h> #include <glib/gtypes.h>
#include <glib/gunicode.h> #include <glib/gunicode.h>

View File

@ -329,58 +329,63 @@ g_date_time_add
g_date_time_add_days g_date_time_add_days
g_date_time_add_full g_date_time_add_full
g_date_time_add_hours g_date_time_add_hours
g_date_time_add_milliseconds
g_date_time_add_minutes g_date_time_add_minutes
g_date_time_add_months g_date_time_add_months
g_date_time_add_seconds g_date_time_add_seconds
g_date_time_add_weeks g_date_time_add_weeks
g_date_time_add_years g_date_time_add_years
g_date_time_compare g_date_time_compare
g_date_time_day
g_date_time_difference g_date_time_difference
g_date_time_equal g_date_time_equal
g_date_time_format G_GNUC_MALLOC
g_date_time_get_day_of_month g_date_time_get_day_of_month
g_date_time_get_day_of_week g_date_time_get_day_of_week
g_date_time_get_day_of_year g_date_time_get_day_of_year
g_date_time_get_dmy
g_date_time_get_hour g_date_time_get_hour
g_date_time_get_julian
g_date_time_get_microsecond g_date_time_get_microsecond
g_date_time_get_millisecond
g_date_time_get_minute g_date_time_get_minute
g_date_time_get_month g_date_time_get_month
g_date_time_get_second g_date_time_get_second
g_date_time_get_timezone_name g_date_time_get_seconds
g_date_time_get_timezone_abbreviation
g_date_time_get_utc_offset g_date_time_get_utc_offset
g_date_time_get_week_of_year g_date_time_get_week_of_year
g_date_time_get_year g_date_time_get_year
g_date_time_get_ymd
g_date_time_hash g_date_time_hash
g_date_time_is_daylight_savings g_date_time_is_daylight_savings
g_date_time_is_leap_year g_date_time_new
g_date_time_new_from_date g_date_time_new_from_timeval_local
g_date_time_new_from_epoch g_date_time_new_from_timeval_utc
g_date_time_new_from_timeval g_date_time_new_from_unix_local
g_date_time_new_full g_date_time_new_from_unix_utc
g_date_time_new_local
g_date_time_new_now g_date_time_new_now
g_date_time_new_today g_date_time_new_now_local
g_date_time_new_utc_now g_date_time_new_now_utc
g_date_time_printf G_GNUC_MALLOC g_date_time_new_utc
g_date_time_ref g_date_time_ref
g_date_time_to_local g_date_time_to_local
g_date_time_to_epoch
g_date_time_to_timeval g_date_time_to_timeval
g_date_time_to_timezone
g_date_time_to_unix
g_date_time_to_utc g_date_time_to_utc
g_date_time_unref g_date_time_unref
g_time_zone_copy #endif
g_time_zone_free #endif
g_time_zone_get_is_dst
g_time_zone_get_name #if IN_HEADER(__G_TIME_ZONE_H__)
g_time_zone_get_offset #if IN_FILE(__G_TIME_ZONE_C__)
g_time_zone_is_floating
g_time_zone_new g_time_zone_new
g_time_zone_new_for_name
g_time_zone_new_local g_time_zone_new_local
g_time_zone_new_utc g_time_zone_new_utc
g_time_zone_ref
g_time_zone_unref
g_time_zone_adjust_time
g_time_zone_find_interval
g_time_zone_get_abbreviation
g_time_zone_get_offset
g_time_zone_is_dst
#endif #endif
#endif #endif

790
glib/gtimezone.c Normal file
View File

@ -0,0 +1,790 @@
/*
* Copyright © 2010 Codethink Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the licence, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
/* Prologue {{{1 */
#include "gtimezone.h"
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include "gmappedfile.h"
#include "gtestutils.h"
#include "gfileutils.h"
#include "gstrfuncs.h"
#include "ghash.h"
#include "gthread.h"
#include "gbuffer.h"
/**
* SECTION:timezone
* @title: GTimeZone
* @short_description: A structure representing a time zone
* @see_also: #GDateTime
*
* #GTimeZone is a structure that represents a time zone, at no
* particular point in time. It is refcounted and immutable.
*
* A time zone contains a number of intervals. Each interval has
* an abbreviation to describe it, an offet to UTC and a flag indicating
* if the daylight savings time is in effect during that interval. A
* time zone always has at least one interval -- interval 0.
*
* Every UTC time is contained within exactly one interval, but a given
* local time may be contained within zero, one or two intervals (due to
* incontinuities associated with daylight savings time).
*
* An interval may refer to a specific period of time (eg: the duration
* of daylight savings time during 2010) or it may refer to many periods
* of time that share the same properties (eg: all periods of daylight
* savings time). It is also possible (usually for political reasons)
* that some properties (like the abbreviation) change between intervals
* without other properties changing.
*
* #GTimeZone is available since GLib 2.26.
*/
/**
* GTimeZone:
*
* #GDateTime is an opaque structure whose members cannot be accessed
* directly.
*
* Since: 2.26
**/
/* zoneinfo file format {{{1 */
/* unaligned */
typedef struct { gchar bytes[8]; } gint64_be;
typedef struct { gchar bytes[4]; } gint32_be;
typedef struct { gchar bytes[4]; } guint32_be;
static inline gint64 gint64_from_be (const gint64_be be) {
gint64 tmp; memcpy (&tmp, &be, sizeof tmp); return GINT64_FROM_BE (tmp);
}
static inline gint32 gint32_from_be (const gint32_be be) {
gint32 tmp; memcpy (&tmp, &be, sizeof tmp); return GINT32_FROM_BE (tmp);
}
static inline guint32 guint32_from_be (const guint32_be be) {
guint32 tmp; memcpy (&tmp, &be, sizeof tmp); return GUINT32_FROM_BE (tmp);
}
struct tzhead
{
gchar tzh_magic[4];
gchar tzh_version;
guchar tzh_reserved[15];
guint32_be tzh_ttisgmtcnt;
guint32_be tzh_ttisstdcnt;
guint32_be tzh_leapcnt;
guint32_be tzh_timecnt;
guint32_be tzh_typecnt;
guint32_be tzh_charcnt;
};
struct ttinfo
{
gint32_be tt_gmtoff;
guint8 tt_isdst;
guint8 tt_abbrind;
};
/* GTimeZone structure and lifecycle {{{1 */
struct _GTimeZone
{
gchar *name;
GBuffer *zoneinfo;
const struct tzhead *header;
const struct ttinfo *infos;
const gint64_be *trans;
const guint8 *indices;
const gchar *abbrs;
gint timecnt;
gint ref_count;
};
G_LOCK_DEFINE_STATIC (time_zones);
static GHashTable/*<string?, GTimeZone>*/ *time_zones;
static guint
g_str_hash0 (gconstpointer data)
{
return data ? g_str_hash (data) : 0;
}
static gboolean
g_str_equal0 (gconstpointer a,
gconstpointer b)
{
if (a == b)
return TRUE;
if (!a || !b)
return FALSE;
return g_str_equal (a, b);
}
/**
* g_time_zone_unref:
* @tz: a #GTimeZone
*
* Decreases the reference count on @tz.
*
* Since: 2.26
**/
void
g_time_zone_unref (GTimeZone *tz)
{
g_assert (tz->ref_count > 0);
if (g_atomic_int_dec_and_test (&tz->ref_count))
{
G_LOCK(time_zones);
g_hash_table_remove (time_zones, tz->name);
G_UNLOCK(time_zones);
if (tz->zoneinfo)
g_buffer_unref (tz->zoneinfo);
g_free (tz->name);
g_slice_free (GTimeZone, tz);
}
}
/**
* g_time_zone_ref:
* @tz: a #GTimeZone
*
* Increases the reference count on @tz.
*
* Returns: a new reference to @tz.
*
* Since: 2.26
**/
GTimeZone *
g_time_zone_ref (GTimeZone *tz)
{
g_assert (tz->ref_count > 0);
g_atomic_int_inc (&tz->ref_count);
return tz;
}
/* fake zoneinfo creation (for RFC3339/ISO 8601 timezones) {{{1 */
/*
* parses strings of the form 'hh' 'hhmm' or 'hh:mm' where:
* - hh is 00 to 23
* - mm is 00 to 59
*/
gboolean
parse_time (const gchar *time,
gint32 *offset)
{
if (*time < '0' || '2' < *time)
return FALSE;
*offset = 10 * 60 * 60 * (*time++ - '0');
if (*time < '0' || '9' < *time)
return FALSE;
*offset += 60 * 60 * (*time++ - '0');
if (*offset > 23 * 60 * 60)
return FALSE;
if (*time == '\0')
return TRUE;
if (*time == ':')
time++;
if (*time < '0' || '5' < *time)
return FALSE;
*offset += 10 * 60 * (*time++ - '0');
if (*time < '0' || '9' < *time)
return FALSE;
*offset += 60 * (*time++ - '0');
return *time == '\0';
}
gboolean
parse_constant_offset (const gchar *name,
gint32 *offset)
{
switch (*name++)
{
case 'Z':
*offset = 0;
return !*name;
case '+':
return parse_time (name, offset);
case '-':
if (parse_time (name, offset))
{
*offset = -*offset;
return TRUE;
}
default:
return FALSE;
}
}
static GBuffer *
zone_for_constant_offset (const gchar *name)
{
const gchar fake_zoneinfo_headers[] =
"TZif" "2..." "...." "...." "...."
"\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0"
"TZif" "2..." "...." "...." "...."
"\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\1" "\0\0\0\7";
struct {
struct tzhead headers[2];
struct ttinfo info;
gchar abbr[8];
} *fake;
gint32 offset;
if (name == NULL || !parse_constant_offset (name, &offset))
return NULL;
offset = GINT32_TO_BE (offset);
fake = g_malloc (sizeof *fake);
memcpy (fake, fake_zoneinfo_headers, sizeof fake_zoneinfo_headers);
memcpy (&fake->info.tt_gmtoff, &offset, sizeof offset);
fake->info.tt_isdst = FALSE;
fake->info.tt_abbrind = 0;
strcpy (fake->abbr, name);
return g_buffer_new_take_data (fake, sizeof *fake);
}
/* Construction {{{1 */
/**
* g_time_zone_new:
* @identifier: (allow-none): a timezone identifier
*
* Creates a #GTimeZone corresponding to @identifier.
*
* @identifier can either be an RFC3339/ISO 8601 time offset or
* something that would pass as a valid value for the
* <varname>TZ</varname> environment variable (including %NULL).
*
* Valid RFC3339 time offsets are <literal>"Z"</literal> (for UTC) or
* <literal>"±hh:mm"</literal>. ISO 8601 additionally specifies
* <literal>"±hhmm"</literal> and <literal>"±hh"</literal>.
*
* The <varname>TZ</varname> environment variable typically corresponds
* to the name of a file in the zoneinfo database, but there are many
* other possibilities. Note that those other possibilities are not
* currently implemented, but are planned.
*
* g_time_zone_new_local() calls this function with the value of the
* <varname>TZ</varname> environment variable. This function itself is
* independent of the value of <varname>TZ</varname>, but if @identifier
* is %NULL then <filename>/etc/localtime</filename> will be consulted
* to discover the correct timezone.
*
* See <ulink
* url='http://tools.ietf.org/html/rfc3339#section-5.6'>RFC3339
* §5.6</ulink> for a precise definition of valid RFC3339 time offsets
* (the <varname>time-offset</varname> expansion) and ISO 8601 for the
* full list of valid time offsets. See <ulink
* url='http://www.gnu.org/s/libc/manual/html_node/TZ-Variable.html'>The
* GNU C Library manual</ulink> for an explanation of the possible
* values of the <varname>TZ</varname> environment variable.
*
* You should release the return value by calling g_time_zone_unref()
* when you are done with it.
*
* Returns: the requested timezone
*
* Since: 2.26
**/
GTimeZone *
g_time_zone_new (const gchar *identifier)
{
GTimeZone *tz;
G_LOCK (time_zones);
if (time_zones == NULL)
time_zones = g_hash_table_new (g_str_hash0,
g_str_equal0);
tz = g_hash_table_lookup (time_zones, identifier);
if (tz == NULL)
{
tz = g_slice_new0 (GTimeZone);
tz->name = g_strdup (identifier);
tz->ref_count = 0;
tz->zoneinfo = zone_for_constant_offset (identifier);
if (tz->zoneinfo == NULL)
{
gchar *filename;
if (identifier != NULL)
{
const gchar *tzdir;
tzdir = getenv ("TZDIR");
if (tzdir == NULL)
tzdir = "/usr/share/zoneinfo";
filename = g_build_filename (tzdir, identifier, NULL);
}
else
filename = g_strdup ("/etc/localtime");
tz->zoneinfo = (GBuffer *) g_mapped_file_new (filename, FALSE, NULL);
g_free (filename);
}
if (tz->zoneinfo != NULL)
{
const struct tzhead *header = tz->zoneinfo->data;
gsize size = tz->zoneinfo->size;
/* we only bother to support version 2 */
if (size < sizeof (struct tzhead) || memcmp (header, "TZif2", 5))
{
g_buffer_unref (tz->zoneinfo);
tz->zoneinfo = NULL;
}
else
{
gint typecnt;
/* we trust the file completely. */
tz->header = (const struct tzhead *)
(((const gchar *) (header + 1)) +
guint32_from_be(header->tzh_ttisgmtcnt) +
guint32_from_be(header->tzh_ttisstdcnt) +
8 * guint32_from_be(header->tzh_leapcnt) +
5 * guint32_from_be(header->tzh_timecnt) +
6 * guint32_from_be(header->tzh_typecnt) +
guint32_from_be(header->tzh_charcnt));
typecnt = guint32_from_be (tz->header->tzh_typecnt);
tz->timecnt = guint32_from_be (tz->header->tzh_timecnt);
tz->trans = (gconstpointer) (tz->header + 1);
tz->indices = (gconstpointer) (tz->trans + tz->timecnt);
tz->infos = (gconstpointer) (tz->indices + tz->timecnt);
tz->abbrs = (gconstpointer) (tz->infos + typecnt);
}
}
g_hash_table_insert (time_zones, tz->name, tz);
}
g_atomic_int_inc (&tz->ref_count);
G_UNLOCK (time_zones);
return tz;
}
/**
* g_time_zone_new_utc:
*
* Creates a #GTimeZone corresponding to UTC.
*
* This is equivalent to calling g_time_zone_new() with a value like
* "Z", "UTC", "+00", etc.
*
* You should release the return value by calling g_time_zone_unref()
* when you are done with it.
*
* Returns: the universal timezone
*
* Since: 2.26
**/
GTimeZone *
g_time_zone_new_utc (void)
{
return g_time_zone_new ("UTC");
}
/**
* g_time_zone_new_local:
*
* Creates a #GTimeZone corresponding to local time.
*
* This is equivalent to calling g_time_zone_new() with the value of the
* <varname>TZ</varname> environment variable (including the possibility
* of %NULL). Changes made to <varname>TZ</varname> after the first
* call to this function may or may not be noticed by future calls.
*
* You should release the return value by calling g_time_zone_unref()
* when you are done with it.
*
* Returns: the local timezone
*
* Since: 2.26
**/
GTimeZone *
g_time_zone_new_local (void)
{
return g_time_zone_new (getenv ("TZ"));
}
/* Internal helpers {{{1 */
inline static const struct ttinfo *
interval_info (GTimeZone *tz,
gint interval)
{
if (interval)
return tz->infos + tz->indices[interval - 1];
return tz->infos;
}
inline static gint64
interval_start (GTimeZone *tz,
gint interval)
{
if (interval)
return gint64_from_be (tz->trans[interval - 1]);
return G_MININT64;
}
inline static gint64
interval_end (GTimeZone *tz,
gint interval)
{
if (interval < tz->timecnt)
return gint64_from_be (tz->trans[interval]) - 1;
return G_MAXINT64;
}
inline static gint32
interval_offset (GTimeZone *tz,
gint interval)
{
return gint32_from_be (interval_info (tz, interval)->tt_gmtoff);
}
inline static gboolean
interval_isdst (GTimeZone *tz,
gint interval)
{
return interval_info (tz, interval)->tt_isdst;
}
inline static guint8
interval_abbrind (GTimeZone *tz,
gint interval)
{
return interval_info (tz, interval)->tt_abbrind;
}
inline static gint64
interval_local_start (GTimeZone *tz,
gint interval)
{
if (interval)
return interval_start (tz, interval) + interval_offset (tz, interval);
return G_MININT64;
}
inline static gint64
interval_local_end (GTimeZone *tz,
gint interval)
{
if (interval < tz->timecnt)
return interval_end (tz, interval) + interval_offset (tz, interval);
return G_MAXINT64;
}
static gboolean
interval_valid (GTimeZone *tz,
gint interval)
{
return interval <= tz->timecnt;
}
/* g_time_zone_find_interval() {{{1 */
/**
* g_time_zone_adjust_time:
* @tz: a #GTimeZone
* @type: the #GTimeType of @time
* @time: a pointer to a number of seconds since January 1, 1970
*
* Finds an interval within @tz that corresponds to the given @time,
* possibly adjusting @time if required to fit into an interval.
* The meaning of @time depends on @type.
*
* This function is similar to g_time_zone_find_interval(), with the
* difference that it always succeeds (by making the adjustments
* described below).
*
* In any of the cases where g_time_zone_find_interval() succeeds then
* this function returns the same value, without modifying @time.
*
* This function may, however, modify @time in order to deal with
* non-existent times. If the non-existent local @time of 02:30 were
* requested on March 13th 2010 in Toronto then this function would
* adjust @time to be 03:00 and return the interval containing the
* adjusted time.
*
* Returns: the interval containing @time, never -1
*
* Since: 2.26
**/
gint
g_time_zone_adjust_time (GTimeZone *tz,
GTimeType type,
gint64 *time)
{
gint i;
if (tz->zoneinfo == NULL)
return 0;
/* find the interval containing *time UTC
* TODO: this could be binary searched (or better) */
for (i = 0; i < tz->timecnt; i++)
if (*time <= interval_end (tz, i))
break;
g_assert (interval_start (tz, i) <= *time && *time <= interval_end (tz, i));
if (type != G_TIME_TYPE_UNIVERSAL)
{
if (*time < interval_local_start (tz, i))
/* if time came before the start of this interval... */
{
i--;
/* if it's not in the previous interval... */
if (*time > interval_local_end (tz, i))
{
/* it doesn't exist. fast-forward it. */
i++;
*time = interval_local_start (tz, i);
}
}
else if (*time > interval_local_end (tz, i))
/* if time came after the end of this interval... */
{
i++;
/* if it's not in the next interval... */
if (*time < interval_local_start (tz, i))
/* it doesn't exist. fast-forward it. */
*time = interval_local_start (tz, i);
}
else if (interval_isdst (tz, i) != type)
/* it's in this interval, but dst flag doesn't match.
* check neighbours for a better fit. */
{
if (i && *time <= interval_local_end (tz, i - 1))
i--;
else if (i < tz->timecnt &&
*time >= interval_local_start (tz, i + 1))
i++;
}
}
return i;
}
/**
* g_time_zone_find_interval:
* @tz: a #GTimeZone
* @type: the #GTimeType of @time
* @time: a number of seconds since January 1, 1970
*
* Finds an the interval within @tz that corresponds to the given @time.
* The meaning of @time depends on @type.
*
* If @type is %G_TIME_TYPE_UNIVERSAL then this function will always
* succeed (since universal time is monotonic and continuous).
*
* Otherwise @time is treated is local time. The distinction between
* %G_TIME_TYPE_STANDARD and %G_TIME_TYPE_DAYLIGHT is ignored except in
* the case that the given @time is ambiguous. In Toronto, for example,
* 01:30 on November 7th 2010 occured twice (once inside of daylight
* savings time and the next, an hour later, outside of daylight savings
* time). In this case, the different value of @type would result in a
* different interval being returned.
*
* It is still possible for this function to fail. In Toronto, for
* example, 02:00 on March 14th 2010 does not exist (due to the leap
* forward to begin daylight savings time). -1 is returned in that
* case.
*
* Returns: the interval containing @time, or -1 in case of failure
*
* Since: 2.26
*/
gint
g_time_zone_find_interval (GTimeZone *tz,
GTimeType type,
gint64 time)
{
gint i;
if (tz->zoneinfo == NULL)
return 0;
for (i = 0; i < tz->timecnt; i++)
if (time <= interval_end (tz, i))
break;
if (type == G_TIME_TYPE_UNIVERSAL)
return i;
if (time < interval_local_start (tz, i))
{
if (time > interval_local_end (tz, --i))
return -1;
}
else if (time > interval_local_end (tz, i))
{
if (time < interval_local_start (tz, ++i))
return -1;
}
else if (interval_isdst (tz, i) != type)
{
if (i && time <= interval_local_end (tz, i - 1))
i--;
else if (i < tz->timecnt && time >= interval_local_start (tz, i + 1))
i++;
}
return i;
}
/* Public API accessors {{{1 */
/**
* g_time_zone_get_abbreviation:
* @tz: a #GTimeZone
* @interval: an interval within the timezone
*
* Determines the time zone abbreviation to be used during a particular
* @interval of time in the time zone @tz.
*
* For example, in Toronto this is currently "EST" during the winter
* months and "EDT" during the summer months when daylight savings time
* is in effect.
*
* Returns: the time zone abbreviation, which belongs to @tz
*
* Since: 2.26
**/
const gchar *
g_time_zone_get_abbreviation (GTimeZone *tz,
gint interval)
{
g_return_val_if_fail (interval_valid (tz, interval), NULL);
if (tz->header == NULL)
return "UTC";
return tz->abbrs + interval_abbrind (tz, interval);
}
/**
* g_time_zone_get_offset:
* @tz: a #GTimeZone
* @interval: an interval within the timezone
*
* Determines the offset to UTC in effect during a particular @interval
* of time in the time zone @tz.
*
* The offset is the number of seconds that you add to UTC time to
* arrive at local time for @tz (ie: negative numbers for time zones
* west of GMT, positive numbers for east).
*
* Returns: the number of seconds that should be added to UTC to get the
* local time in @tz
*
* Since: 2.26
**/
gint32
g_time_zone_get_offset (GTimeZone *tz,
gint interval)
{
g_return_val_if_fail (interval_valid (tz, interval), 0);
if (tz->header == NULL)
return 0;
return interval_offset (tz, interval);
}
/**
* g_time_zone_is_dst:
* @tz: a #GTimeZone
* @interval: an interval within the timezone
*
* Determines if daylight savings time is in effect during a particular
* @interval of time in the time zone @tz.
*
* Returns: %TRUE if daylight savings time is in effect
*
* Since: 2.26
**/
gboolean
g_time_zone_is_dst (GTimeZone *tz,
gint interval)
{
g_return_val_if_fail (interval_valid (tz, interval), FALSE);
if (tz->header == NULL)
return FALSE;
return interval_isdst (tz, interval);
}
/* Epilogue {{{1 */
/* vim:set foldmethod=marker: */

81
glib/gtimezone.h Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright © 2010 Codethink Limited
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* licence, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
#error "Only <glib.h> can be included directly."
#endif
#ifndef __G_TIME_ZONE_H__
#define __G_TIME_ZONE_H__
#include <glib/gtypes.h>
G_BEGIN_DECLS
typedef struct _GTimeZone GTimeZone;
/**
* GTimeType:
* @G_TIME_TYPE_STANDARD: the time is in local standard time
* @G_TIME_TYPE_DAYLIGHT: the time is in local daylight time
* @G_TIME_TYPE_UNIVERSAL: the time is in UTC
*
* Disambiguates a given time in two ways.
*
* First, specifies if the given time is in universal or local time.
*
* Second, if the time is in local time, specifies if it is local
* standard time or local daylight time. This is important for the case
* where the same local time occurs twice (during daylight savings time
* transitions, for example).
*/
typedef enum
{
G_TIME_TYPE_STANDARD,
G_TIME_TYPE_DAYLIGHT,
G_TIME_TYPE_UNIVERSAL
} GTimeType;
GTimeZone * g_time_zone_new (const gchar *identifier);
GTimeZone * g_time_zone_new_utc (void);
GTimeZone * g_time_zone_new_local (void);
GTimeZone * g_time_zone_ref (GTimeZone *tz);
void g_time_zone_unref (GTimeZone *tz);
gint g_time_zone_find_interval (GTimeZone *tz,
GTimeType type,
gint64 time);
gint g_time_zone_adjust_time (GTimeZone *tz,
GTimeType type,
gint64 *time);
const gchar * g_time_zone_get_abbreviation (GTimeZone *tz,
gint interval);
gint32 g_time_zone_get_offset (GTimeZone *tz,
gint interval);
gboolean g_time_zone_is_dst (GTimeZone *tz,
gint interval);
G_END_DECLS
#endif /* __G_TIME_ZONE_H__ */

View File

@ -73,7 +73,7 @@ test_GDateTime_now (void)
memset (&tm, 0, sizeof (tm)); memset (&tm, 0, sizeof (tm));
get_localtime_tm (time (NULL), &tm); get_localtime_tm (time (NULL), &tm);
dt = g_date_time_new_now (); dt = g_date_time_new_now_local ();
g_assert_cmpint (g_date_time_get_year (dt), ==, 1900 + tm.tm_year); g_assert_cmpint (g_date_time_get_year (dt), ==, 1900 + tm.tm_year);
g_assert_cmpint (g_date_time_get_month (dt), ==, 1 + tm.tm_mon); g_assert_cmpint (g_date_time_get_month (dt), ==, 1 + tm.tm_mon);
@ -87,27 +87,7 @@ test_GDateTime_now (void)
} }
static void static void
test_GDateTime_today (void) test_GDateTime_new_from_unix (void)
{
GDateTime *dt;
struct tm tm;
memset (&tm, 0, sizeof (tm));
get_localtime_tm (time (NULL), &tm);
dt = g_date_time_new_today ();
g_assert_cmpint (g_date_time_get_year (dt), ==, 1900 + tm.tm_year);
g_assert_cmpint (g_date_time_get_month (dt), ==, 1 + tm.tm_mon);
g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, tm.tm_mday);
g_assert_cmpint (g_date_time_get_hour (dt), ==, 0);
g_assert_cmpint (g_date_time_get_minute (dt), ==, 0);
g_assert_cmpint (g_date_time_get_second (dt), ==, 0);
g_assert_cmpint (g_date_time_get_millisecond (dt), ==, 0);
g_date_time_unref (dt);
}
static void
test_GDateTime_new_from_epoch (void)
{ {
GDateTime *dt; GDateTime *dt;
struct tm tm; struct tm tm;
@ -117,7 +97,7 @@ test_GDateTime_new_from_epoch (void)
t = time (NULL); t = time (NULL);
get_localtime_tm (t, &tm); get_localtime_tm (t, &tm);
dt = g_date_time_new_from_epoch (t); dt = g_date_time_new_from_unix_local (t);
g_assert_cmpint (g_date_time_get_year (dt), ==, 1900 + tm.tm_year); g_assert_cmpint (g_date_time_get_year (dt), ==, 1900 + tm.tm_year);
g_assert_cmpint (g_date_time_get_month (dt), ==, 1 + tm.tm_mon); g_assert_cmpint (g_date_time_get_month (dt), ==, 1 + tm.tm_mon);
g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, tm.tm_mday); g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, tm.tm_mday);
@ -135,7 +115,7 @@ test_GDateTime_new_from_epoch (void)
tm.tm_sec = 0; tm.tm_sec = 0;
t = mktime (&tm); t = mktime (&tm);
dt = g_date_time_new_from_epoch (t); dt = g_date_time_new_from_unix_local (t);
g_assert_cmpint (g_date_time_get_year (dt), ==, 1970); g_assert_cmpint (g_date_time_get_year (dt), ==, 1970);
g_assert_cmpint (g_date_time_get_month (dt), ==, 1); g_assert_cmpint (g_date_time_get_month (dt), ==, 1);
g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 1); g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 1);
@ -145,109 +125,73 @@ test_GDateTime_new_from_epoch (void)
g_date_time_unref (dt); g_date_time_unref (dt);
} }
static void
test_GDateTime_is_leap_year (void)
{
GDateTime *dt;
gint i;
for (i = 1; i <= 3000; i++)
{
dt = g_date_time_new_from_date (i, 1, 1);
if ((((i % 4) == 0) && ((i % 100) != 0)) || ((i % 400) == 0))
g_assert (g_date_time_is_leap_year (dt));
else
g_assert (!g_date_time_is_leap_year (dt));
g_date_time_unref (dt);
}
}
static void static void
test_GDateTime_compare (void) test_GDateTime_compare (void)
{ {
GDateTime *dt1, *dt2; GDateTime *dt1, *dt2;
gint i; gint i;
dt1 = g_date_time_new_from_date (2000, 1, 1); dt1 = g_date_time_new_utc (2000, 1, 1, 0, 0, 0);
for (i = 1; i < 2000; i++) for (i = 1; i < 2000; i++)
{ {
dt2 = g_date_time_new_from_date (i, 12, 31); dt2 = g_date_time_new_utc (i, 12, 31, 0, 0, 0);
g_assert_cmpint (1, ==, g_date_time_compare (dt1, dt2)); g_assert_cmpint (1, ==, g_date_time_compare (dt1, dt2));
g_date_time_unref (dt2); g_date_time_unref (dt2);
} }
dt2 = g_date_time_new_full (1999, 12, 31, 23, 59, 59, NULL); dt2 = g_date_time_new_utc (1999, 12, 31, 23, 59, 59);
g_assert_cmpint (1, ==, g_date_time_compare (dt1, dt2)); g_assert_cmpint (1, ==, g_date_time_compare (dt1, dt2));
g_date_time_unref (dt2); g_date_time_unref (dt2);
dt2 = g_date_time_new_full (2000, 1, 1, 0, 0, 1, NULL); dt2 = g_date_time_new_utc (2000, 1, 1, 0, 0, 1);
g_assert_cmpint (-1, ==, g_date_time_compare (dt1, dt2)); g_assert_cmpint (-1, ==, g_date_time_compare (dt1, dt2));
g_date_time_unref (dt2); g_date_time_unref (dt2);
dt2 = g_date_time_new_full (2000, 1, 1, 0, 0, 0, NULL); dt2 = g_date_time_new_utc (2000, 1, 1, 0, 0, 0);
g_assert_cmpint (0, ==, g_date_time_compare (dt1, dt2)); g_assert_cmpint (0, ==, g_date_time_compare (dt1, dt2));
g_date_time_unref (dt2); g_date_time_unref (dt2);
g_date_time_unref (dt1); g_date_time_unref (dt1);
} }
static void
test_GDateTime_date (void)
{
GDateTime *dt1, *dt2;
dt1 = g_date_time_new_full (2009, 10, 19, 13, 0, 55, NULL);
dt2 = g_date_time_day (dt1);
g_assert (dt1 != NULL);
g_assert (dt2 != NULL);
g_assert_cmpint (2009, ==, g_date_time_get_year (dt2));
g_assert_cmpint (10, ==, g_date_time_get_month (dt2));
g_assert_cmpint (19, ==, g_date_time_get_day_of_month (dt2));
g_assert_cmpint (0, ==, g_date_time_get_hour (dt2));
g_assert_cmpint (0, ==, g_date_time_get_minute (dt2));
g_assert_cmpint (0, ==, g_date_time_get_second (dt2));
g_date_time_unref (dt1);
g_date_time_unref (dt2);
}
static void static void
test_GDateTime_equal (void) test_GDateTime_equal (void)
{ {
GDateTime *dt1, *dt2; GDateTime *dt1, *dt2;
GTimeZone *time_zone; GTimeZone *tz;
dt1 = g_date_time_new_from_date (2009, 10, 19); dt1 = g_date_time_new_local (2009, 10, 19, 0, 0, 0);
dt2 = g_date_time_new_from_date (2009, 10, 19); dt2 = g_date_time_new_local (2009, 10, 19, 0, 0, 0);
g_assert (g_date_time_equal (dt1, dt2)); g_assert (g_date_time_equal (dt1, dt2));
g_date_time_unref (dt1); g_date_time_unref (dt1);
g_date_time_unref (dt2); g_date_time_unref (dt2);
dt1 = g_date_time_new_from_date (2009, 10, 18); dt1 = g_date_time_new_local (2009, 10, 18, 0, 0, 0);
dt2 = g_date_time_new_from_date (2009, 10, 19); dt2 = g_date_time_new_local (2009, 10, 19, 0, 0, 0);
g_assert (!g_date_time_equal (dt1, dt2)); g_assert (!g_date_time_equal (dt1, dt2));
g_date_time_unref (dt1); g_date_time_unref (dt1);
g_date_time_unref (dt2); g_date_time_unref (dt2);
/* UTC-0300 and not in DST */ /* UTC-0300 and not in DST */
time_zone = g_time_zone_new (-3 * 3600, FALSE); tz = g_time_zone_new ("-03:00");
dt1 = g_date_time_new_full (2010, 5, 24, 8, 0, 0, time_zone); dt1 = g_date_time_new (tz, 2010, 5, 24, 8, 0, 0);
g_time_zone_unref (tz);
g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600)); g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600));
/* UTC */ /* UTC */
dt2 = g_date_time_new_full (2010, 5, 24, 11, 0, 0, NULL); dt2 = g_date_time_new_utc (2010, 5, 24, 11, 0, 0);
g_assert_cmpint (g_date_time_get_utc_offset (dt2), ==, 0); g_assert_cmpint (g_date_time_get_utc_offset (dt2), ==, 0);
g_assert (g_date_time_equal (dt1, dt2)); g_assert (g_date_time_equal (dt1, dt2));
g_date_time_unref (dt1); g_date_time_unref (dt1);
g_time_zone_free (time_zone);
/* America/Recife is in UTC-0300 */ /* America/Recife is in UTC-0300 */
time_zone = g_time_zone_new_for_name ("America/Recife"); tz = g_time_zone_new ("America/Recife");
dt1 = g_date_time_new_full (2010, 5, 24, 8, 0, 0, time_zone); dt1 = g_date_time_new (tz, 2010, 5, 24, 8, 0, 0);
g_time_zone_unref (tz);
g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600)); g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, (-3 * 3600));
g_assert (g_date_time_equal (dt1, dt2)); g_assert (g_date_time_equal (dt1, dt2));
g_date_time_unref (dt1); g_date_time_unref (dt1);
g_date_time_unref (dt2); g_date_time_unref (dt2);
g_time_zone_free (time_zone);
} }
static void static void
@ -255,11 +199,11 @@ test_GDateTime_get_day_of_week (void)
{ {
GDateTime *dt; GDateTime *dt;
dt = g_date_time_new_from_date (2009, 10, 19); dt = g_date_time_new_local (2009, 10, 19, 0, 0, 0);
g_assert_cmpint (1, ==, g_date_time_get_day_of_week (dt)); g_assert_cmpint (1, ==, g_date_time_get_day_of_week (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_from_date (2000, 10, 1); dt = g_date_time_new_local (2000, 10, 1, 0, 0, 0);
g_assert_cmpint (7, ==, g_date_time_get_day_of_week (dt)); g_assert_cmpint (7, ==, g_date_time_get_day_of_week (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
} }
@ -269,25 +213,25 @@ test_GDateTime_get_day_of_month (void)
{ {
GDateTime *dt; GDateTime *dt;
dt = g_date_time_new_from_date (2009, 10, 19); dt = g_date_time_new_local (2009, 10, 19, 0, 0, 0);
g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 19); g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 19);
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_from_date (1400, 3, 12); dt = g_date_time_new_local (1400, 3, 12, 0, 0, 0);
g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 12); g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 12);
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_from_date (1800, 12, 31); dt = g_date_time_new_local (1800, 12, 31, 0, 0, 0);
g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 31); g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 31);
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_from_date (1000, 1, 1); dt = g_date_time_new_local (1000, 1, 1, 0, 0, 0);
g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 1); g_assert_cmpint (g_date_time_get_day_of_month (dt), ==, 1);
g_date_time_unref (dt); g_date_time_unref (dt);
} }
static void static void
test_GDateTime_get_dmy (void) test_GDateTime_get_ymd (void)
{ {
GDateTime *dt; GDateTime *dt;
struct tm tm; struct tm tm;
@ -301,8 +245,8 @@ test_GDateTime_get_dmy (void)
memset (&tm, 0, sizeof (struct tm)); memset (&tm, 0, sizeof (struct tm));
get_localtime_tm (t, &tm); get_localtime_tm (t, &tm);
dt = g_date_time_new_from_epoch (t); dt = g_date_time_new_from_unix_utc (t);
g_date_time_get_dmy(dt, &d, &m, &y); g_date_time_get_ymd(dt, &y, &m, &d);
g_assert_cmpint(y, ==, tm.tm_year + 1900); g_assert_cmpint(y, ==, tm.tm_year + 1900);
g_assert_cmpint(m, ==, tm.tm_mon + 1); g_assert_cmpint(m, ==, tm.tm_mon + 1);
g_assert_cmpint(d, ==, tm.tm_mday); g_assert_cmpint(d, ==, tm.tm_mday);
@ -318,9 +262,9 @@ test_GDateTime_get_dmy (void)
{ {
for (d = 1; d <= days[leap][m]; d++) for (d = 1; d <= days[leap][m]; d++)
{ {
GDateTime *dt1 = g_date_time_new_from_date (y, m, d); GDateTime *dt1 = g_date_time_new_utc (y, m, d, 0, 0, 0);
g_date_time_get_dmy (dt1, &d2, &m2, &y2); g_date_time_get_ymd (dt1, &y2, &m2, &d2);
g_assert_cmpint (y, ==, y2); g_assert_cmpint (y, ==, y2);
g_assert_cmpint (m, ==, m2); g_assert_cmpint (m, ==, m2);
g_assert_cmpint (d, ==, d2); g_assert_cmpint (d, ==, d2);
@ -335,39 +279,23 @@ test_GDateTime_get_hour (void)
{ {
GDateTime *dt; GDateTime *dt;
dt = g_date_time_new_full (2009, 10, 19, 15, 13, 11, NULL); dt = g_date_time_new_utc (2009, 10, 19, 15, 13, 11);
g_assert_cmpint (15, ==, g_date_time_get_hour (dt)); g_assert_cmpint (15, ==, g_date_time_get_hour (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_full (100, 10, 19, 1, 0, 0, NULL); dt = g_date_time_new_utc (100, 10, 19, 1, 0, 0);
g_assert_cmpint (1, ==, g_date_time_get_hour (dt)); g_assert_cmpint (1, ==, g_date_time_get_hour (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_full (100, 10, 19, 0, 0, 0, NULL); dt = g_date_time_new_utc (100, 10, 19, 0, 0, 0);
g_assert_cmpint (0, ==, g_date_time_get_hour (dt)); g_assert_cmpint (0, ==, g_date_time_get_hour (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_full (100, 10, 1, 23, 59, 59, NULL); dt = g_date_time_new_utc (100, 10, 1, 23, 59, 59);
g_assert_cmpint (23, ==, g_date_time_get_hour (dt)); g_assert_cmpint (23, ==, g_date_time_get_hour (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
} }
static void
test_GDateTime_get_julian (void)
{
GDateTime *dt;
gint period, julian, hour = 1, min = 1, sec = 1;
dt = g_date_time_new_from_date (1984, 8, 16);
g_date_time_get_julian (dt, &period, &julian, &hour, &min, &sec);
g_assert_cmpint (period, ==, 0);
g_assert_cmpint (julian, ==, 2445929);
g_assert_cmpint (hour, ==, 0);
g_assert_cmpint (min, ==, 0);
g_assert_cmpint (sec, ==, 0);
g_date_time_unref (dt);
}
static void static void
test_GDateTime_get_microsecond (void) test_GDateTime_get_microsecond (void)
{ {
@ -375,46 +303,29 @@ test_GDateTime_get_microsecond (void)
GDateTime *dt; GDateTime *dt;
g_get_current_time (&tv); g_get_current_time (&tv);
dt = g_date_time_new_from_timeval (&tv); dt = g_date_time_new_from_timeval_local (&tv);
g_assert_cmpint (tv.tv_usec, ==, g_date_time_get_microsecond (dt)); g_assert_cmpint (tv.tv_usec, ==, g_date_time_get_microsecond (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
} }
static void
test_GDateTime_get_millisecond (void)
{
GTimeVal tv;
GDateTime *dt;
g_get_current_time (&tv);
dt = g_date_time_new_from_timeval (&tv);
g_assert_cmpint ((tv.tv_usec / 1000), ==, g_date_time_get_millisecond (dt));
g_date_time_unref (dt);
dt = g_date_time_new_full (2010, 9, 15, 12, 0, 0.1234, NULL);
g_assert_cmpint (123, ==, g_date_time_get_millisecond (dt));
g_assert_cmpint (123400, ==, g_date_time_get_microsecond (dt));
g_date_time_unref (dt);
}
static void static void
test_GDateTime_get_year (void) test_GDateTime_get_year (void)
{ {
GDateTime *dt; GDateTime *dt;
dt = g_date_time_new_from_date (2009, 1, 1); dt = g_date_time_new_local (2009, 1, 1, 0, 0, 0);
g_assert_cmpint (2009, ==, g_date_time_get_year (dt)); g_assert_cmpint (2009, ==, g_date_time_get_year (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_from_date (1, 1, 1); dt = g_date_time_new_local (1, 1, 1, 0, 0, 0);
g_assert_cmpint (1, ==, g_date_time_get_year (dt)); g_assert_cmpint (1, ==, g_date_time_get_year (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_from_date (13, 1, 1); dt = g_date_time_new_local (13, 1, 1, 0, 0, 0);
g_assert_cmpint (13, ==, g_date_time_get_year (dt)); g_assert_cmpint (13, ==, g_date_time_get_year (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
dt = g_date_time_new_from_date (3000, 1, 1); dt = g_date_time_new_local (3000, 1, 1, 0, 0, 0);
g_assert_cmpint (3000, ==, g_date_time_get_year (dt)); g_assert_cmpint (3000, ==, g_date_time_get_year (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
} }
@ -427,7 +338,7 @@ test_GDateTime_hash (void)
h = g_hash_table_new_full (g_date_time_hash, g_date_time_equal, h = g_hash_table_new_full (g_date_time_hash, g_date_time_equal,
(GDestroyNotify)g_date_time_unref, (GDestroyNotify)g_date_time_unref,
NULL); NULL);
g_hash_table_insert (h, g_date_time_new_now (), NULL); g_hash_table_insert (h, g_date_time_new_now_local (), NULL);
g_hash_table_remove_all (h); g_hash_table_remove_all (h);
g_hash_table_destroy (h); g_hash_table_destroy (h);
} }
@ -439,7 +350,7 @@ test_GDateTime_new_from_timeval (void)
GTimeVal tv, tv2; GTimeVal tv, tv2;
g_get_current_time (&tv); g_get_current_time (&tv);
dt = g_date_time_new_from_timeval (&tv); dt = g_date_time_new_from_timeval_local (&tv);
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("\nDT%04d-%02d-%02dT%02d:%02d:%02d%s\n", g_print ("\nDT%04d-%02d-%02dT%02d:%02d:%02d%s\n",
@ -449,7 +360,7 @@ test_GDateTime_new_from_timeval (void)
g_date_time_get_hour (dt), g_date_time_get_hour (dt),
g_date_time_get_minute (dt), g_date_time_get_minute (dt),
g_date_time_get_second (dt), g_date_time_get_second (dt),
g_date_time_get_timezone_name (dt)); g_date_time_get_timezone_abbreviation (dt));
g_date_time_to_timeval (dt, &tv2); g_date_time_to_timeval (dt, &tv2);
g_assert_cmpint (tv.tv_sec, ==, tv2.tv_sec); g_assert_cmpint (tv.tv_sec, ==, tv2.tv_sec);
@ -458,14 +369,14 @@ test_GDateTime_new_from_timeval (void)
} }
static void static void
test_GDateTime_to_epoch (void) test_GDateTime_to_unix (void)
{ {
GDateTime *dt; GDateTime *dt;
time_t t; time_t t;
t = time (NULL); t = time (NULL);
dt = g_date_time_new_from_epoch (t); dt = g_date_time_new_from_unix_local (t);
g_assert_cmpint (g_date_time_to_epoch (dt), ==, t); g_assert_cmpint (g_date_time_to_unix (dt), ==, t);
g_date_time_unref (dt); g_date_time_unref (dt);
} }
@ -474,7 +385,7 @@ test_GDateTime_add_years (void)
{ {
GDateTime *dt, *dt2; GDateTime *dt, *dt2;
dt = g_date_time_new_from_date (2009, 10, 19); dt = g_date_time_new_local (2009, 10, 19, 0, 0, 0);
dt2 = g_date_time_add_years (dt, 1); dt2 = g_date_time_add_years (dt, 1);
g_assert_cmpint (2010, ==, g_date_time_get_year (dt2)); g_assert_cmpint (2010, ==, g_date_time_get_year (dt2));
g_date_time_unref (dt); g_date_time_unref (dt);
@ -484,11 +395,9 @@ test_GDateTime_add_years (void)
static void static void
test_GDateTime_add_months (void) test_GDateTime_add_months (void)
{ {
GTimeZone *utc_tz = g_time_zone_new_utc ();
#define TEST_ADD_MONTHS(y,m,d,a,ny,nm,nd) G_STMT_START { \ #define TEST_ADD_MONTHS(y,m,d,a,ny,nm,nd) G_STMT_START { \
GDateTime *dt, *dt2; \ GDateTime *dt, *dt2; \
dt = g_date_time_new_full (y, m, d, 0, 0, 0, utc_tz); \ dt = g_date_time_new_utc (y, m, d, 0, 0, 0); \
dt2 = g_date_time_add_months (dt, a); \ dt2 = g_date_time_add_months (dt, a); \
ASSERT_DATE (dt2, ny, nm, nd); \ ASSERT_DATE (dt2, ny, nm, nd); \
g_date_time_unref (dt); \ g_date_time_unref (dt); \
@ -506,8 +415,6 @@ test_GDateTime_add_months (void)
TEST_ADD_MONTHS (2000, 8, 16, -12, 1999, 8, 16); TEST_ADD_MONTHS (2000, 8, 16, -12, 1999, 8, 16);
TEST_ADD_MONTHS (2011, 2, 1, -13, 2010, 1, 1); TEST_ADD_MONTHS (2011, 2, 1, -13, 2010, 1, 1);
TEST_ADD_MONTHS (1776, 7, 4, 1200, 1876, 7, 4); TEST_ADD_MONTHS (1776, 7, 4, 1200, 1876, 7, 4);
g_time_zone_free (utc_tz);
} }
static void static void
@ -515,7 +422,7 @@ test_GDateTime_add_days (void)
{ {
#define TEST_ADD_DAYS(y,m,d,a,ny,nm,nd) G_STMT_START { \ #define TEST_ADD_DAYS(y,m,d,a,ny,nm,nd) G_STMT_START { \
GDateTime *dt, *dt2; \ GDateTime *dt, *dt2; \
dt = g_date_time_new_from_date (y, m, d); \ dt = g_date_time_new_local (y, m, d, 0, 0, 0); \
dt2 = g_date_time_add_days (dt, a); \ dt2 = g_date_time_add_days (dt, a); \
g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \
g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \
@ -538,7 +445,7 @@ test_GDateTime_add_weeks (void)
{ {
#define TEST_ADD_WEEKS(y,m,d,a,ny,nm,nd) G_STMT_START { \ #define TEST_ADD_WEEKS(y,m,d,a,ny,nm,nd) G_STMT_START { \
GDateTime *dt, *dt2; \ GDateTime *dt, *dt2; \
dt = g_date_time_new_from_date (y, m, d); \ dt = g_date_time_new_local (y, m, d, 0, 0, 0); \
dt2 = g_date_time_add_weeks (dt, a); \ dt2 = g_date_time_add_weeks (dt, a); \
g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \
g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \
@ -558,7 +465,7 @@ test_GDateTime_add_hours (void)
{ {
#define TEST_ADD_HOURS(y,m,d,h,mi,s,a,ny,nm,nd,nh,nmi,ns) G_STMT_START { \ #define TEST_ADD_HOURS(y,m,d,h,mi,s,a,ny,nm,nd,nh,nmi,ns) G_STMT_START { \
GDateTime *dt, *dt2; \ GDateTime *dt, *dt2; \
dt = g_date_time_new_full (y, m, d, h, mi, s, NULL); \ dt = g_date_time_new_utc (y, m, d, h, mi, s); \
dt2 = g_date_time_add_hours (dt, a); \ dt2 = g_date_time_add_hours (dt, a); \
g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \
g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \
@ -579,7 +486,7 @@ test_GDateTime_add_full (void)
{ {
#define TEST_ADD_FULL(y,m,d,h,mi,s,ay,am,ad,ah,ami,as,ny,nm,nd,nh,nmi,ns) G_STMT_START { \ #define TEST_ADD_FULL(y,m,d,h,mi,s,ay,am,ad,ah,ami,as,ny,nm,nd,nh,nmi,ns) G_STMT_START { \
GDateTime *dt, *dt2; \ GDateTime *dt, *dt2; \
dt = g_date_time_new_full (y, m, d, h, mi, s, NULL); \ dt = g_date_time_new_utc (y, m, d, h, mi, s); \
dt2 = g_date_time_add_full (dt, ay, am, ad, ah, ami, as); \ dt2 = g_date_time_add_full (dt, ay, am, ad, ah, ami, as); \
g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \ g_assert_cmpint (ny, ==, g_date_time_get_year (dt2)); \
g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \ g_assert_cmpint (nm, ==, g_date_time_get_month (dt2)); \
@ -608,30 +515,12 @@ test_GDateTime_add_full (void)
2010, 10, 2, 0, 10, 0); 2010, 10, 2, 0, 10, 0);
} }
static void
test_GDateTime_add_milliseconds (void)
{
#define TEST_ADD_MILLISECOND(i,o) G_STMT_START { \
GDateTime *dt, *dt2; \
dt = g_date_time_new_from_date (2000, 1, 1); \
dt2 = g_date_time_add_milliseconds (dt, i); \
g_assert_cmpint (o, ==, g_date_time_get_millisecond (dt2)); \
g_date_time_unref (dt); \
g_date_time_unref (dt2); \
} G_STMT_END
TEST_ADD_MILLISECOND (199, 199);
TEST_ADD_MILLISECOND (10001, 1);
TEST_ADD_MILLISECOND (22201, 201);
TEST_ADD_MILLISECOND (-1000, 0);
}
static void static void
test_GDateTime_add_minutes (void) test_GDateTime_add_minutes (void)
{ {
#define TEST_ADD_MINUTES(i,o) G_STMT_START { \ #define TEST_ADD_MINUTES(i,o) G_STMT_START { \
GDateTime *dt, *dt2; \ GDateTime *dt, *dt2; \
dt = g_date_time_new_from_date (2000, 1, 1); \ dt = g_date_time_new_local (2000, 1, 1, 0, 0, 0); \
dt2 = g_date_time_add_minutes (dt, i); \ dt2 = g_date_time_add_minutes (dt, i); \
g_assert_cmpint (o, ==, g_date_time_get_minute (dt2)); \ g_assert_cmpint (o, ==, g_date_time_get_minute (dt2)); \
g_date_time_unref (dt); \ g_date_time_unref (dt); \
@ -641,8 +530,8 @@ test_GDateTime_add_minutes (void)
TEST_ADD_MINUTES (60, 0); TEST_ADD_MINUTES (60, 0);
TEST_ADD_MINUTES (100, 40); TEST_ADD_MINUTES (100, 40);
TEST_ADD_MINUTES (5, 5); TEST_ADD_MINUTES (5, 5);
TEST_ADD_MINUTES (86401, 1); TEST_ADD_MINUTES (1441, 1);
TEST_ADD_MINUTES (-86401, 59); TEST_ADD_MINUTES (-1441, 59);
} }
static void static void
@ -650,7 +539,7 @@ test_GDateTime_add_seconds (void)
{ {
#define TEST_ADD_SECONDS(i,o) G_STMT_START { \ #define TEST_ADD_SECONDS(i,o) G_STMT_START { \
GDateTime *dt, *dt2; \ GDateTime *dt, *dt2; \
dt = g_date_time_new_from_date (2000, 1, 1); \ dt = g_date_time_new_local (2000, 1, 1, 0, 0, 0); \
dt2 = g_date_time_add_seconds (dt, i); \ dt2 = g_date_time_add_seconds (dt, i); \
g_assert_cmpint (o, ==, g_date_time_get_second (dt2)); \ g_assert_cmpint (o, ==, g_date_time_get_second (dt2)); \
g_date_time_unref (dt); \ g_date_time_unref (dt); \
@ -674,9 +563,9 @@ test_GDateTime_diff (void)
#define TEST_DIFF(y,m,d,y2,m2,d2,u) G_STMT_START { \ #define TEST_DIFF(y,m,d,y2,m2,d2,u) G_STMT_START { \
GDateTime *dt1, *dt2; \ GDateTime *dt1, *dt2; \
GTimeSpan ts = 0; \ GTimeSpan ts = 0; \
dt1 = g_date_time_new_from_date (y, m, d); \ dt1 = g_date_time_new_local (y, m, d, 0, 0, 0); \
dt2 = g_date_time_new_from_date (y2, m2, d2); \ dt2 = g_date_time_new_local (y2, m2, d2, 0, 0, 0); \
ts = g_date_time_difference (dt1, dt2); \ ts = g_date_time_difference (dt2, dt1); \
g_assert_cmpint (ts, ==, u); \ g_assert_cmpint (ts, ==, u); \
g_date_time_unref (dt1); \ g_date_time_unref (dt1); \
g_date_time_unref (dt2); \ g_date_time_unref (dt2); \
@ -695,7 +584,7 @@ test_GDateTime_get_minute (void)
{ {
GDateTime *dt; GDateTime *dt;
dt = g_date_time_new_full (2009, 12, 1, 1, 31, 0, NULL); dt = g_date_time_new_utc (2009, 12, 1, 1, 31, 0);
g_assert_cmpint (31, ==, g_date_time_get_minute (dt)); g_assert_cmpint (31, ==, g_date_time_get_minute (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
} }
@ -705,7 +594,7 @@ test_GDateTime_get_month (void)
{ {
GDateTime *dt; GDateTime *dt;
dt = g_date_time_new_full (2009, 12, 1, 1, 31, 0, NULL); dt = g_date_time_new_utc (2009, 12, 1, 1, 31, 0);
g_assert_cmpint (12, ==, g_date_time_get_month (dt)); g_assert_cmpint (12, ==, g_date_time_get_month (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
} }
@ -715,30 +604,18 @@ test_GDateTime_get_second (void)
{ {
GDateTime *dt; GDateTime *dt;
dt = g_date_time_new_full (2009, 12, 1, 1, 31, 44, NULL); dt = g_date_time_new_utc (2009, 12, 1, 1, 31, 44);
g_assert_cmpint (44, ==, g_date_time_get_second (dt)); g_assert_cmpint (44, ==, g_date_time_get_second (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
} }
static void
test_GDateTime_new_from_date (void)
{
GDateTime *dt;
dt = g_date_time_new_from_date (2009, 12, 11);
g_assert_cmpint (2009, ==, g_date_time_get_year (dt));
g_assert_cmpint (12, ==, g_date_time_get_month (dt));
g_assert_cmpint (11, ==, g_date_time_get_day_of_month (dt));
g_date_time_unref (dt);
}
static void static void
test_GDateTime_new_full (void) test_GDateTime_new_full (void)
{ {
GTimeZone *tz;
GDateTime *dt; GDateTime *dt;
GTimeZone *time_zone;
dt = g_date_time_new_full (2009, 12, 11, 12, 11, 10, NULL); dt = g_date_time_new_utc (2009, 12, 11, 12, 11, 10);
g_assert_cmpint (2009, ==, g_date_time_get_year (dt)); g_assert_cmpint (2009, ==, g_date_time_get_year (dt));
g_assert_cmpint (12, ==, g_date_time_get_month (dt)); g_assert_cmpint (12, ==, g_date_time_get_month (dt));
g_assert_cmpint (11, ==, g_date_time_get_day_of_month (dt)); g_assert_cmpint (11, ==, g_date_time_get_day_of_month (dt));
@ -747,22 +624,22 @@ test_GDateTime_new_full (void)
g_assert_cmpint (10, ==, g_date_time_get_second (dt)); g_assert_cmpint (10, ==, g_date_time_get_second (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
time_zone = g_time_zone_new_for_name ("America/Recife"); tz = g_time_zone_new ("America/Recife");
dt = g_date_time_new_full (2010, 5, 24, 8, 4, 0, time_zone); dt = g_date_time_new (tz, 2010, 5, 24, 8, 4, 0);
g_time_zone_unref (tz);
g_assert_cmpint (2010, ==, g_date_time_get_year (dt)); g_assert_cmpint (2010, ==, g_date_time_get_year (dt));
g_assert_cmpint (5, ==, g_date_time_get_month (dt)); g_assert_cmpint (5, ==, g_date_time_get_month (dt));
g_assert_cmpint (24, ==, g_date_time_get_day_of_month (dt)); g_assert_cmpint (24, ==, g_date_time_get_day_of_month (dt));
g_assert_cmpint (8, ==, g_date_time_get_hour (dt)); g_assert_cmpint (8, ==, g_date_time_get_hour (dt));
g_assert_cmpint (4, ==, g_date_time_get_minute (dt)); g_assert_cmpint (4, ==, g_date_time_get_minute (dt));
g_assert_cmpint (0, ==, g_date_time_get_second (dt)); g_assert_cmpint (0, ==, g_date_time_get_second (dt));
g_assert_cmpstr ("BRT", ==, g_date_time_get_timezone_name (dt)); g_assert_cmpstr ("BRT", ==, g_date_time_get_timezone_abbreviation (dt));
g_assert (!g_date_time_is_daylight_savings (dt)); g_assert (!g_date_time_is_daylight_savings (dt));
g_date_time_unref (dt); g_date_time_unref (dt);
g_time_zone_free (time_zone);
} }
static void static void
test_GDateTime_utc_now (void) test_GDateTime_now_utc (void)
{ {
GDateTime *dt; GDateTime *dt;
time_t t; time_t t;
@ -781,7 +658,7 @@ test_GDateTime_utc_now (void)
memcpy (&tm, tmp, sizeof (struct tm)); memcpy (&tm, tmp, sizeof (struct tm));
} }
#endif #endif
dt = g_date_time_new_utc_now (); dt = g_date_time_new_now_utc ();
g_assert_cmpint (tm.tm_year + 1900, ==, g_date_time_get_year (dt)); g_assert_cmpint (tm.tm_year + 1900, ==, g_date_time_get_year (dt));
g_assert_cmpint (tm.tm_mon + 1, ==, g_date_time_get_month (dt)); g_assert_cmpint (tm.tm_mon + 1, ==, g_date_time_get_month (dt));
g_assert_cmpint (tm.tm_mday, ==, g_date_time_get_day_of_month (dt)); g_assert_cmpint (tm.tm_mday, ==, g_date_time_get_day_of_month (dt));
@ -801,7 +678,7 @@ test_GDateTime_get_utc_offset (void)
memset (&tm, 0, sizeof (tm)); memset (&tm, 0, sizeof (tm));
get_localtime_tm (time (NULL), &tm); get_localtime_tm (time (NULL), &tm);
dt = g_date_time_new_now (); dt = g_date_time_new_now_local ();
ts = g_date_time_get_utc_offset (dt); ts = g_date_time_get_utc_offset (dt);
#ifdef HAVE_STRUCT_TM_TM_GMTOFF #ifdef HAVE_STRUCT_TM_TM_GMTOFF
g_assert_cmpint (ts, ==, (tm.tm_gmtoff * G_TIME_SPAN_SECOND)); g_assert_cmpint (ts, ==, (tm.tm_gmtoff * G_TIME_SPAN_SECOND));
@ -819,7 +696,7 @@ test_GDateTime_to_timeval (void)
memset (&tv2, 0, sizeof (tv2)); memset (&tv2, 0, sizeof (tv2));
g_get_current_time (&tv1); g_get_current_time (&tv1);
dt = g_date_time_new_from_timeval (&tv1); dt = g_date_time_new_from_timeval_local (&tv1);
g_date_time_to_timeval (dt, &tv2); g_date_time_to_timeval (dt, &tv2);
g_assert_cmpint (tv1.tv_sec, ==, tv2.tv_sec); g_assert_cmpint (tv1.tv_sec, ==, tv2.tv_sec);
g_assert_cmpint (tv1.tv_usec, ==, tv2.tv_usec); g_assert_cmpint (tv1.tv_usec, ==, tv2.tv_usec);
@ -831,8 +708,8 @@ test_GDateTime_to_local (void)
{ {
GDateTime *utc, *now, *dt; GDateTime *utc, *now, *dt;
utc = g_date_time_new_utc_now (); utc = g_date_time_new_now_utc ();
now = g_date_time_new_now (); now = g_date_time_new_now_local ();
dt = g_date_time_to_local (utc); dt = g_date_time_to_local (utc);
g_assert_cmpint (g_date_time_get_year (now), ==, g_date_time_get_year (dt)); g_assert_cmpint (g_date_time_get_year (now), ==, g_date_time_get_year (dt));
@ -863,7 +740,7 @@ test_GDateTime_to_utc (void)
memcpy (&tm, tmp, sizeof (struct tm)); memcpy (&tm, tmp, sizeof (struct tm));
} }
#endif #endif
dt2 = g_date_time_new_now (); dt2 = g_date_time_new_now_local ();
dt = g_date_time_to_utc (dt2); dt = g_date_time_to_utc (dt2);
g_assert_cmpint (tm.tm_year + 1900, ==, g_date_time_get_year (dt)); g_assert_cmpint (tm.tm_year + 1900, ==, g_date_time_get_year (dt));
g_assert_cmpint (tm.tm_mon + 1, ==, g_date_time_get_month (dt)); g_assert_cmpint (tm.tm_mon + 1, ==, g_date_time_get_month (dt));
@ -879,7 +756,7 @@ static void
test_GDateTime_get_day_of_year (void) test_GDateTime_get_day_of_year (void)
{ {
#define TEST_DAY_OF_YEAR(y,m,d,o) G_STMT_START { \ #define TEST_DAY_OF_YEAR(y,m,d,o) G_STMT_START { \
GDateTime *__dt = g_date_time_new_from_date ((y), (m), (d)); \ GDateTime *__dt = g_date_time_new_local ((y), (m), (d), 0, 0, 0); \
g_assert_cmpint ((o), ==, g_date_time_get_day_of_year (__dt)); \ g_assert_cmpint ((o), ==, g_date_time_get_day_of_year (__dt)); \
g_date_time_unref (__dt); } G_STMT_END g_date_time_unref (__dt); } G_STMT_END
@ -898,21 +775,21 @@ test_GDateTime_printf (void)
gchar t_str[16]; gchar t_str[16];
#define TEST_PRINTF(f,o) G_STMT_START { \ #define TEST_PRINTF(f,o) G_STMT_START { \
GDateTime *__dt = g_date_time_new_from_date (2009, 10, 24); \ GDateTime *__dt = g_date_time_new_local (2009, 10, 24, 0, 0, 0);\
gchar *__p = g_date_time_format (__dt, (f)); \ gchar *__p = g_date_time_format (__dt, (f)); \
g_assert_cmpstr (__p, ==, (o)); \ g_assert_cmpstr (__p, ==, (o)); \
g_date_time_unref (__dt); \ g_date_time_unref (__dt); \
g_free (__p); } G_STMT_END g_free (__p); } G_STMT_END
#define TEST_PRINTF_DATE(y,m,d,f,o) G_STMT_START { \ #define TEST_PRINTF_DATE(y,m,d,f,o) G_STMT_START { \
GDateTime *dt = g_date_time_new_from_date ((y), (m), (d)); \ GDateTime *dt = g_date_time_new_local (y, m, d, 0, 0, 0); \
gchar *p = g_date_time_format (dt, (f)); \ gchar *p = g_date_time_format (dt, (f)); \
g_assert_cmpstr (p, ==, (o)); \ g_assert_cmpstr (p, ==, (o)); \
g_date_time_unref (dt); \ g_date_time_unref (dt); \
g_free (p); } G_STMT_END g_free (p); } G_STMT_END
#define TEST_PRINTF_TIME(h,m,s,f,o) G_STMT_START { \ #define TEST_PRINTF_TIME(h,m,s,f,o) G_STMT_START { \
GDateTime *dt = g_date_time_new_full (2009, 10, 24, (h), (m), (s), NULL); \ GDateTime *dt = g_date_time_new_local (2009, 10, 24, (h), (m), (s)); \
gchar *p = g_date_time_format (dt, (f)); \ gchar *p = g_date_time_format (dt, (f)); \
g_assert_cmpstr (p, ==, (o)); \ g_assert_cmpstr (p, ==, (o)); \
g_date_time_unref (dt); \ g_date_time_unref (dt); \
@ -991,36 +868,34 @@ test_GDateTime_dst (void)
GDateTime *dt1, *dt2; GDateTime *dt1, *dt2;
GTimeZone *tz; GTimeZone *tz;
tz = g_time_zone_new_for_name ("Europe/London");
/* this date has the DST state set for Europe/London */ /* this date has the DST state set for Europe/London */
dt1 = g_date_time_new_full (2009, 8, 15, 3, 0, 1, tz); tz = g_time_zone_new ("Europe/London");
dt1 = g_date_time_new (tz, 2009, 8, 15, 3, 0, 1);
g_assert (g_date_time_is_daylight_savings (dt1)); g_assert (g_date_time_is_daylight_savings (dt1));
g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, 3600); g_assert_cmpint (g_date_time_get_utc_offset (dt1) / G_USEC_PER_SEC, ==, 3600);
g_assert_cmpint (g_date_time_get_hour (dt1), ==, 3); g_assert_cmpint (g_date_time_get_hour (dt1), ==, 3);
/* add 6 months to clear the DST flag and go back one hour */ /* add 6 months to clear the DST flag but keep the same time */
dt2 = g_date_time_add_months (dt1, 6); dt2 = g_date_time_add_months (dt1, 6);
g_assert (!g_date_time_is_daylight_savings (dt2)); g_assert (!g_date_time_is_daylight_savings (dt2));
g_assert_cmpint (g_date_time_get_utc_offset (dt2) / G_USEC_PER_SEC, ==, 0); g_assert_cmpint (g_date_time_get_utc_offset (dt2) / G_USEC_PER_SEC, ==, 0);
g_assert_cmpint (g_date_time_get_hour (dt2), ==, 2);
g_date_time_unref (dt2);
g_date_time_unref (dt1);
/* now do the reverse: start with a non-DST state and move to DST */
dt1 = g_date_time_new_full (2009, 2, 15, 2, 0, 1, tz);
g_assert (!g_date_time_is_daylight_savings (dt1));
g_assert_cmpint (g_date_time_get_hour (dt1), ==, 2);
dt2 = g_date_time_add_months (dt1, 6);
g_assert (g_date_time_is_daylight_savings (dt2));
g_assert_cmpint (g_date_time_get_hour (dt2), ==, 3); g_assert_cmpint (g_date_time_get_hour (dt2), ==, 3);
g_date_time_unref (dt2); g_date_time_unref (dt2);
g_date_time_unref (dt1); g_date_time_unref (dt1);
g_time_zone_free (tz); /* now do the reverse: start with a non-DST state and move to DST */
dt1 = g_date_time_new (tz, 2009, 2, 15, 2, 0, 1);
g_assert (!g_date_time_is_daylight_savings (dt1));
g_assert_cmpint (g_date_time_get_hour (dt1), ==, 2);
dt2 = g_date_time_add_months (dt1, 6);
g_assert (g_date_time_is_daylight_savings (dt2));
g_assert_cmpint (g_date_time_get_hour (dt2), ==, 2);
g_date_time_unref (dt2);
g_date_time_unref (dt1);
g_time_zone_unref (tz);
} }
gint gint
@ -1034,43 +909,36 @@ main (gint argc,
g_test_add_func ("/GDateTime/add_days", test_GDateTime_add_days); g_test_add_func ("/GDateTime/add_days", test_GDateTime_add_days);
g_test_add_func ("/GDateTime/add_full", test_GDateTime_add_full); g_test_add_func ("/GDateTime/add_full", test_GDateTime_add_full);
g_test_add_func ("/GDateTime/add_hours", test_GDateTime_add_hours); g_test_add_func ("/GDateTime/add_hours", test_GDateTime_add_hours);
g_test_add_func ("/GDateTime/add_milliseconds", test_GDateTime_add_milliseconds);
g_test_add_func ("/GDateTime/add_minutes", test_GDateTime_add_minutes); g_test_add_func ("/GDateTime/add_minutes", test_GDateTime_add_minutes);
g_test_add_func ("/GDateTime/add_months", test_GDateTime_add_months); g_test_add_func ("/GDateTime/add_months", test_GDateTime_add_months);
g_test_add_func ("/GDateTime/add_seconds", test_GDateTime_add_seconds); g_test_add_func ("/GDateTime/add_seconds", test_GDateTime_add_seconds);
g_test_add_func ("/GDateTime/add_weeks", test_GDateTime_add_weeks); g_test_add_func ("/GDateTime/add_weeks", test_GDateTime_add_weeks);
g_test_add_func ("/GDateTime/add_years", test_GDateTime_add_years); g_test_add_func ("/GDateTime/add_years", test_GDateTime_add_years);
g_test_add_func ("/GDateTime/compare", test_GDateTime_compare); g_test_add_func ("/GDateTime/compare", test_GDateTime_compare);
g_test_add_func ("/GDateTime/date", test_GDateTime_date);
g_test_add_func ("/GDateTime/diff", test_GDateTime_diff); g_test_add_func ("/GDateTime/diff", test_GDateTime_diff);
g_test_add_func ("/GDateTime/equal", test_GDateTime_equal); g_test_add_func ("/GDateTime/equal", test_GDateTime_equal);
g_test_add_func ("/GDateTime/get_day_of_week", test_GDateTime_get_day_of_week); g_test_add_func ("/GDateTime/get_day_of_week", test_GDateTime_get_day_of_week);
g_test_add_func ("/GDateTime/get_day_of_month", test_GDateTime_get_day_of_month); g_test_add_func ("/GDateTime/get_day_of_month", test_GDateTime_get_day_of_month);
g_test_add_func ("/GDateTime/get_day_of_year", test_GDateTime_get_day_of_year); g_test_add_func ("/GDateTime/get_day_of_year", test_GDateTime_get_day_of_year);
g_test_add_func ("/GDateTime/get_dmy", test_GDateTime_get_dmy); g_test_add_func ("/GDateTime/get_ymd", test_GDateTime_get_ymd);
g_test_add_func ("/GDateTime/get_hour", test_GDateTime_get_hour); g_test_add_func ("/GDateTime/get_hour", test_GDateTime_get_hour);
g_test_add_func ("/GDateTime/get_julian", test_GDateTime_get_julian);
g_test_add_func ("/GDateTime/get_microsecond", test_GDateTime_get_microsecond); g_test_add_func ("/GDateTime/get_microsecond", test_GDateTime_get_microsecond);
g_test_add_func ("/GDateTime/get_millisecond", test_GDateTime_get_millisecond);
g_test_add_func ("/GDateTime/get_minute", test_GDateTime_get_minute); g_test_add_func ("/GDateTime/get_minute", test_GDateTime_get_minute);
g_test_add_func ("/GDateTime/get_month", test_GDateTime_get_month); g_test_add_func ("/GDateTime/get_month", test_GDateTime_get_month);
g_test_add_func ("/GDateTime/get_second", test_GDateTime_get_second); g_test_add_func ("/GDateTime/get_second", test_GDateTime_get_second);
g_test_add_func ("/GDateTime/get_utc_offset", test_GDateTime_get_utc_offset); g_test_add_func ("/GDateTime/get_utc_offset", test_GDateTime_get_utc_offset);
g_test_add_func ("/GDateTime/get_year", test_GDateTime_get_year); g_test_add_func ("/GDateTime/get_year", test_GDateTime_get_year);
g_test_add_func ("/GDateTime/hash", test_GDateTime_hash); g_test_add_func ("/GDateTime/hash", test_GDateTime_hash);
g_test_add_func ("/GDateTime/is_leap_year", test_GDateTime_is_leap_year); g_test_add_func ("/GDateTime/new_from_unix", test_GDateTime_new_from_unix);
g_test_add_func ("/GDateTime/new_from_date", test_GDateTime_new_from_date);
g_test_add_func ("/GDateTime/new_from_epoch", test_GDateTime_new_from_epoch);
g_test_add_func ("/GDateTime/new_from_timeval", test_GDateTime_new_from_timeval); g_test_add_func ("/GDateTime/new_from_timeval", test_GDateTime_new_from_timeval);
g_test_add_func ("/GDateTime/new_full", test_GDateTime_new_full); g_test_add_func ("/GDateTime/new_full", test_GDateTime_new_full);
g_test_add_func ("/GDateTime/now", test_GDateTime_now); g_test_add_func ("/GDateTime/now", test_GDateTime_now);
g_test_add_func ("/GDateTime/printf", test_GDateTime_printf); g_test_add_func ("/GDateTime/printf", test_GDateTime_printf);
g_test_add_func ("/GDateTime/to_local", test_GDateTime_to_local); g_test_add_func ("/GDateTime/to_local", test_GDateTime_to_local);
g_test_add_func ("/GDateTime/to_epoch", test_GDateTime_to_epoch); g_test_add_func ("/GDateTime/to_unix", test_GDateTime_to_unix);
g_test_add_func ("/GDateTime/to_timeval", test_GDateTime_to_timeval); g_test_add_func ("/GDateTime/to_timeval", test_GDateTime_to_timeval);
g_test_add_func ("/GDateTime/to_utc", test_GDateTime_to_utc); g_test_add_func ("/GDateTime/to_utc", test_GDateTime_to_utc);
g_test_add_func ("/GDateTime/today", test_GDateTime_today); g_test_add_func ("/GDateTime/now_utc", test_GDateTime_now_utc);
g_test_add_func ("/GDateTime/utc_now", test_GDateTime_utc_now);
g_test_add_func ("/GDateTime/dst", test_GDateTime_dst); g_test_add_func ("/GDateTime/dst", test_GDateTime_dst);
return g_test_run (); return g_test_run ();