[gmime: 3/4] Migrated to using GDateTime instead of time_t and an int tz_offset



commit 0a7954b26e3b0d9951691f72f5b53284b75401a1
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date:   Mon Mar 27 13:20:21 2017 -0400

    Migrated to using GDateTime instead of time_t and an int tz_offset

 gmime/gmime-message.c |   56 +++++-----
 gmime/gmime-message.h |   13 +--
 gmime/gmime-utils.c   |  284 +++++++++++++++++++++----------------------------
 gmime/gmime-utils.h   |    4 +-
 tests/test-mbox.c     |   14 ++-
 tests/test-mime.c     |   36 +++++--
 6 files changed, 189 insertions(+), 218 deletions(-)
---
diff --git a/gmime/gmime-message.c b/gmime/gmime-message.c
index 2aa8618..0b4c7f5 100644
--- a/gmime/gmime-message.c
+++ b/gmime/gmime-message.c
@@ -197,8 +197,7 @@ g_mime_message_init (GMimeMessage *message, GMimeMessageClass *klass)
        message->message_id = NULL;
        message->mime_part = NULL;
        message->subject = NULL;
-       message->tz_offset = 0;
-       message->date = 0;
+       message->date = NULL;
        
        /* initialize recipient lists */
        for (i = 0; i < N_ADDRESS_TYPES; i++) {
@@ -223,6 +222,9 @@ g_mime_message_finalize (GObject *object)
        g_free (message->message_id);
        g_free (message->subject);
        
+       if (message->date)
+               g_date_time_unref (message->date);
+       
        /* unref child mime part */
        if (message->mime_part)
                g_object_unref (message->mime_part);
@@ -298,8 +300,6 @@ process_header (GMimeObject *object, GMimeHeader *header)
        GMimeParserOptions *options = _g_mime_header_list_get_options (object->headers);
        GMimeMessage *message = (GMimeMessage *) object;
        const char *name, *value;
-       time_t date;
-       int offset;
        guint i;
        
        name = g_mime_header_get_name (header);
@@ -338,9 +338,10 @@ process_header (GMimeObject *object, GMimeHeader *header)
                break;
        case HEADER_DATE:
                if ((value = g_mime_header_get_value (header))) {
-                       date = g_mime_utils_header_decode_date (value, &offset);
-                       message->date = date;
-                       message->tz_offset = offset;
+                       if (message->date)
+                               g_date_time_unref (message->date);
+                       
+                       message->date = g_mime_utils_header_decode_date (value);
                }
                break;
        case HEADER_MESSAGE_ID:
@@ -411,8 +412,10 @@ message_header_removed (GMimeObject *object, GMimeHeader *header)
                message->subject = NULL;
                break;
        case HEADER_DATE:
-               message->date = 0;
-               message->tz_offset = 0;
+               if (message->date) {
+                       g_date_time_unref (message->date);
+                       message->date = NULL;
+               }
                break;
        case HEADER_MESSAGE_ID:
                g_free (message->message_id);
@@ -439,8 +442,11 @@ message_headers_cleared (GMimeObject *object)
        message->message_id = NULL;
        g_free (message->subject);
        message->subject = NULL;
-       message->tz_offset = 0;
-       message->date = 0;
+       
+       if (message->date) {
+               g_date_time_unref (message->date);
+               message->date = NULL;
+       }
        
        GMIME_OBJECT_CLASS (parent_class)->headers_cleared (object);
 }
@@ -919,21 +925,17 @@ g_mime_message_get_subject (GMimeMessage *message)
  * g_mime_message_set_date:
  * @message: A #GMimeMessage
  * @date: a date to be used in the Date header
- * @tz_offset: timezone offset (in +/- hours)
  * 
  * Sets the Date header on a MIME Message.
  **/
 void
-g_mime_message_set_date (GMimeMessage *message, time_t date, int tz_offset)
+g_mime_message_set_date (GMimeMessage *message, GDateTime *date)
 {
        char *str;
        
        g_return_if_fail (GMIME_IS_MESSAGE (message));
        
-       message->date = date;
-       message->tz_offset = tz_offset;
-       
-       str = g_mime_utils_header_format_date (date, tz_offset);
+       str = g_mime_utils_header_format_date (date);
        g_mime_object_set_header ((GMimeObject *) message, "Date", str, NULL);
        g_free (str);
 }
@@ -942,23 +944,17 @@ g_mime_message_set_date (GMimeMessage *message, time_t date, int tz_offset)
 /**
  * g_mime_message_get_date:
  * @message: A #GMimeMessage
- * @date: (out): pointer to a date in time_t
- * @tz_offset: (out): pointer to timezone offset (in +/- hours)
  * 
- * Stores the date in time_t format in @date. If @tz_offset is
- * non-%NULL, then the timezone offset in will be stored in
- * @tz_offset.
+ * Gets the parsed date and time value from the Date header.
+ *
+ * Returns: a #GDateTime on success or %NULL if the date could not be parsed.
  **/
-void
-g_mime_message_get_date (GMimeMessage *message, time_t *date, int *tz_offset)
+GDateTime *
+g_mime_message_get_date (GMimeMessage *message)
 {
-       g_return_if_fail (GMIME_IS_MESSAGE (message));
-       g_return_if_fail (date != NULL);
-       
-       *date = message->date;
+       g_return_val_if_fail (GMIME_IS_MESSAGE (message), NULL);
        
-       if (tz_offset)
-               *tz_offset = message->tz_offset;
+       return message->date;
 }
 
 
diff --git a/gmime/gmime-message.h b/gmime/gmime-message.h
index 85a04ac..f1ab970 100644
--- a/gmime/gmime-message.h
+++ b/gmime/gmime-message.h
@@ -68,12 +68,11 @@ typedef enum _GMimeAddressType {
 /**
  * GMimeMessage:
  * @parent_object: parent #GMimeObject
- * @mime_part: toplevel MIME part
  * @addrlists: a table of address lists
+ * @mime_part: toplevel MIME part
  * @message_id: Message-Id string
- * @subject: Subject string
  * @date: Date value
- * @tz_offset: timezone offset
+ * @subject: Subject string
  *
  * A MIME Message object.
  **/
@@ -83,11 +82,9 @@ struct _GMimeMessage {
        InternetAddressList **addrlists;
        GMimeObject *mime_part;
        char *message_id;
+       GDateTime *date;
        char *subject;
        
-       int tz_offset;
-       time_t date;
-       
        /* < private > */
        GMimeRfcComplianceMode compliance;
 };
@@ -116,8 +113,8 @@ InternetAddressList *g_mime_message_get_all_recipients (GMimeMessage *message);
 void g_mime_message_set_subject (GMimeMessage *message, const char *subject, const char *charset);
 const char *g_mime_message_get_subject (GMimeMessage *message);
 
-void g_mime_message_set_date (GMimeMessage *message, time_t date, int tz_offset);
-void g_mime_message_get_date (GMimeMessage *message, time_t *date, int *tz_offset);
+void g_mime_message_set_date (GMimeMessage *message, GDateTime *date);
+GDateTime *g_mime_message_get_date (GMimeMessage *message);
 
 void g_mime_message_set_message_id (GMimeMessage *message, const char *message_id);
 const char *g_mime_message_get_message_id (GMimeMessage *message);
diff --git a/gmime/gmime-utils.c b/gmime/gmime-utils.c
index ebe6747..3461ba1 100644
--- a/gmime/gmime-utils.c
+++ b/gmime/gmime-utils.c
@@ -187,35 +187,40 @@ static char *tm_days[] = {
 
 /**
  * g_mime_utils_header_format_date:
- * @date: time_t date representation
- * @tz_offset: Timezone offset
+ * @date: a #GDateTime
  *
  * Allocates a string buffer containing the rfc822 formatted date
- * string represented by @time and @tz_offset.
+ * string represented by @date.
  *
  * Returns: a valid string representation of the date.
  **/
 char *
-g_mime_utils_header_format_date (time_t date, int tz_offset)
+g_mime_utils_header_format_date (GDateTime *date)
 {
-       struct tm tm;
+       int wday, year, month, day, hour, min, sec, tz_offset, sign;
+       GTimeSpan tz;
        
-       date += ((tz_offset / 100) * (60 * 60)) + (tz_offset % 100) * 60;
+       g_return_val_if_fail (date != NULL, NULL);
        
-#if defined (HAVE_GMTIME_R)
-       gmtime_r (&date, &tm);
-#elif defined (HAVE_GMTIME_S)
-       gmtime_s (&tm, &date);
-#else
-       memcpy (&tm, gmtime (&date), sizeof (tm));
-#endif
+       wday = g_date_time_get_day_of_week (date);
+       year = g_date_time_get_year (date);
+       month = g_date_time_get_month (date);
+       day = g_date_time_get_day_of_month (date);
+       hour = g_date_time_get_hour (date);
+       min = g_date_time_get_minute (date);
+       sec = g_date_time_get_second (date);
+       tz = g_date_time_get_utc_offset (date);
+       
+       sign = tz < 0 ? -1 : 1;
+       tz *= sign;
+       
+       tz_offset = 100 * (tz / G_TIME_SPAN_HOUR);
+       tz_offset += (tz % G_TIME_SPAN_HOUR) / G_TIME_SPAN_MINUTE;
+       tz_offset *= sign;
        
        return g_strdup_printf ("%s, %02d %s %04d %02d:%02d:%02d %+05d",
-                               tm_days[tm.tm_wday], tm.tm_mday,
-                               tm_months[tm.tm_mon],
-                               tm.tm_year + 1900,
-                               tm.tm_hour, tm.tm_min, tm.tm_sec,
-                               tz_offset);
+                               tm_days[wday % 7], day, tm_months[month - 1],
+                               year, hour, min, sec, tz_offset);
 }
 
 /* This is where it gets ugly... */
@@ -289,14 +294,16 @@ decode_int (const char *in, size_t inlen)
        if (*inptr == '-') {
                sign = -1;
                inptr++;
-       } else if (*inptr == '+')
+       } else if (*inptr == '+') {
                inptr++;
+       }
        
-       for ( ; inptr < inend; inptr++) {
+       while (inptr < inend) {
                if (!(*inptr >= '0' && *inptr <= '9'))
                        return -1;
-               else
-                       val = (val * 10) + (*inptr - '0');
+               
+               val = (val * 10) + (*inptr - '0');
+               inptr++;
        }
        
        val *= sign;
@@ -378,7 +385,7 @@ get_month (const char *in, size_t inlen)
        
        for (i = 0; i < 12; i++) {
                if (!g_ascii_strncasecmp (in, tm_months[i], 3))
-                       return i;
+                       return i + 1;
        }
        
        return -1;  /* unknown month */
@@ -436,149 +443,112 @@ get_time (const char *in, size_t inlen, int *hour, int *min, int *sec)
        return TRUE;
 }
 
-static int
+static GTimeZone *
 get_tzone (date_token **token)
 {
        const char *inptr, *inend;
-       size_t inlen;
-       int i, t;
+       char tzone[8];
+       GTimeZone *tz;
+       size_t len, n;
+       int value, i;
+       guint t;
        
        for (i = 0; *token && i < 2; *token = (*token)->next, i++) {
                inptr = (*token)->start;
-               inlen = (*token)->len;
-               inend = inptr + inlen;
+               len = (*token)->len;
+               inend = inptr + len;
                
-               if (*inptr == '+' || *inptr == '-') {
-                       return decode_int (inptr, inlen);
-               } else {
-                       if (*inptr == '(') {
-                               inptr++;
-                               if (*(inend - 1) == ')')
-                                       inlen -= 2;
-                               else
-                                       inlen--;
-                       }
+               if (len >= 6)
+                       continue;
+               
+               if (len == 5 && (*inptr == '+' || *inptr == '-')) {
+                       if ((value = decode_int (inptr, len)) == -1)
+                               return NULL;
                        
-                       for (t = 0; t < 15; t++) {
-                               size_t len = strlen (tz_offsets[t].name);
-                               
-                               if (len != inlen)
-                                       continue;
-                               
-                               if (!strncmp (inptr, tz_offsets[t].name, len))
-                                       return tz_offsets[t].offset;
-                       }
+                       memcpy (tzone, inptr, len);
+                       tzone[len] = '\0';
+                       
+                       return g_time_zone_new (tzone);
                }
-       }
-       
-       return -1;
-}
-
-static time_t
-mktime_utc (struct tm *tm)
-{
-       time_t tt;
-       long tz;
-       
-       tm->tm_isdst = -1;
-       tt = mktime (tm);
-       
-#if defined (G_OS_WIN32) && !defined (__MINGW32__)
-       _get_timezone (&tz);
-       if (tm->tm_isdst > 0) {
-               int dst;
                
-               _get_dstbias (&dst);
-               tz += dst;
-       }
-#elif defined (HAVE_TM_GMTOFF)
-       tz = -tm->tm_gmtoff;
-#elif defined (HAVE_TIMEZONE)
-       if (tm->tm_isdst > 0) {
-#if defined (HAVE_ALTZONE)
-               tz = altzone;
-#else /* !defined (HAVE_ALTZONE) */
-               tz = (timezone - 3600);
-#endif
-       } else {
-               tz = timezone;
+               if (*inptr == '(') {
+                       inptr++;
+                       if (*(inend - 1) == ')')
+                               len -= 2;
+                       else
+                               len--;
+               }
+               
+               for (t = 0; t < G_N_ELEMENTS (tz_offsets); t++) {
+                       n = strlen (tz_offsets[t].name);
+                       
+                       if (n != len || strncmp (inptr, tz_offsets[t].name, n) != 0)
+                               continue;
+                       
+                       snprintf (tzone, 6, "%+05d", tz_offsets[t].offset);
+                       
+                       return g_time_zone_new (tzone);
+               }
        }
-#elif defined (HAVE__TIMEZONE)
-       tz = _timezone;
-#else
-#error Neither HAVE_TIMEZONE nor HAVE_TM_GMTOFF defined. Rerun autoheader, autoconf, etc.
-#endif
        
-       return tt - tz;
+       return NULL;
 }
 
-static time_t
-parse_rfc822_date (date_token *tokens, int *tzone)
+static GDateTime *
+parse_rfc822_date (date_token *tokens)
 {
-       int hour, min, sec, offset, n;
+       int wday, year, month, day, hour, min, sec, n;
+       GTimeZone *tz = NULL;
        date_token *token;
-       struct tm tm;
-       time_t t;
+       GDateTime *date;
        
        token = tokens;
        
-       memset ((void *) &tm, 0, sizeof (struct tm));
+       wday = year = month = day = hour = min = sec = 0;
        
        if ((n = get_wday (token->start, token->len)) != -1) {
                /* not all dates may have this... */
-               tm.tm_wday = n;
                token = token->next;
+               wday = n;
        }
        
        /* get the mday */
        if (!token || (n = get_mday (token->start, token->len)) == -1)
-               return (time_t) 0;
+               return NULL;
        
-       tm.tm_mday = n;
        token = token->next;
+       day = n;
        
        /* get the month */
        if (!token || (n = get_month (token->start, token->len)) == -1)
-               return (time_t) 0;
+               return NULL;
        
-       tm.tm_mon = n;
        token = token->next;
+       month = n;
        
        /* get the year */
        if (!token || (n = get_year (token->start, token->len)) == -1)
-               return (time_t) 0;
+               return NULL;
        
-       tm.tm_year = n - 1900;
        token = token->next;
+       year = n;
        
        /* get the hour/min/sec */
        if (!token || !get_time (token->start, token->len, &hour, &min, &sec))
-               return (time_t) 0;
+               return NULL;
        
-       tm.tm_hour = hour;
-       tm.tm_min = min;
-       tm.tm_sec = sec;
        token = token->next;
        
        /* get the timezone */
-       if (!token || (n = get_tzone (&token)) == -1) {
+       if (!token || !(tz = get_tzone (&token))) {
                /* I guess we assume tz is GMT? */
-               offset = 0;
-       } else {
-               offset = n;
+               tz = g_time_zone_new_utc ();
        }
        
-       t = mktime_utc (&tm);
-       
-       /* t is now GMT of the time we want, but not offset by the timezone ... */
-       
-       /* this should convert the time to the GMT equiv time */
-       t -= ((offset / 100) * 60 * 60) + (offset % 100) * 60;
-       
-       if (tzone)
-               *tzone = offset;
+       date = g_date_time_new (tz, year, month, day, hour, min, (gdouble) sec);
+       g_time_zone_unref (tz);
        
-       return t;
+       return date;
 }
 
 
@@ -598,17 +568,16 @@ parse_rfc822_date (date_token *tokens, int *tzone)
 #define TIME    (1 << 4)
 #define TZONE   (1 << 5)
 
-static time_t
-parse_broken_date (date_token *tokens, int *tzone)
+static GDateTime *
+parse_broken_date (date_token *tokens)
 {
-       int hour, min, sec, offset, n;
+       int wday, year, month, day, hour, min, sec, n;
+       GTimeZone *tz = NULL;
        date_token *token;
-       struct tm tm;
-       time_t t;
+       GDateTime *date;
        int mask;
        
-       memset ((void *) &tm, 0, sizeof (struct tm));
-       offset = 0;
+       wday = year = month = day = hour = min = sec = 0;
        mask = 0;
        
        token = tokens;
@@ -617,7 +586,7 @@ parse_broken_date (date_token *tokens, int *tzone)
                        if ((n = get_wday (token->start, token->len)) != -1) {
                                d(printf ("weekday; "));
                                mask |= WEEKDAY;
-                               tm.tm_wday = n;
+                               wday = n;
                                goto next;
                        }
                }
@@ -626,17 +595,14 @@ parse_broken_date (date_token *tokens, int *tzone)
                        if ((n = get_month (token->start, token->len)) != -1) {
                                d(printf ("month; "));
                                mask |= MONTH;
-                               tm.tm_mon = n;
+                               month = n;
                                goto next;
                        }
                }
                
-               if (is_time (token) && !tm.tm_hour && !tm.tm_min && !tm.tm_sec) {
+               if (is_time (token) && !(mask & TIME)) {
                        if (get_time (token->start, token->len, &hour, &min, &sec)) {
                                d(printf ("time; "));
-                               tm.tm_hour = hour;
-                               tm.tm_min = min;
-                               tm.tm_sec = sec;
                                mask |= TIME;
                                goto next;
                        }
@@ -645,10 +611,9 @@ parse_broken_date (date_token *tokens, int *tzone)
                if (is_tzone (token) && !(mask & TZONE)) {
                        date_token *t = token;
                        
-                       if ((n = get_tzone (&t)) != -1) {
+                       if ((tz = get_tzone (&t))) {
                                d(printf ("tzone; "));
                                mask |= TZONE;
-                               offset = n;
                                goto next;
                        }
                }
@@ -657,8 +622,8 @@ parse_broken_date (date_token *tokens, int *tzone)
                        if (token->len == 4 && !(mask & YEAR)) {
                                if ((n = get_year (token->start, token->len)) != -1) {
                                        d(printf ("year; "));
-                                       tm.tm_year = n - 1900;
                                        mask |= YEAR;
+                                       year = n;
                                        goto next;
                                }
                        } else {
@@ -668,21 +633,21 @@ parse_broken_date (date_token *tokens, int *tzone)
                                                goto mday;
                                        } else if (n > 0) {
                                                d(printf ("mon; "));
-                                               tm.tm_mon = n - 1;
                                                mask |= MONTH;
+                                               month = n;
                                        }
                                        goto next;
                                } else if (!(mask & DAY) && (n = get_mday (token->start, token->len)) != -1) {
                                mday:
                                        d(printf ("mday; "));
-                                       tm.tm_mday = n;
                                        mask |= DAY;
+                                       day = n;
                                        goto next;
                                } else if (!(mask & YEAR)) {
                                        if ((n = get_year (token->start, token->len)) != -1) {
                                                d(printf ("2-digit year; "));
-                                               tm.tm_year = n - 1900;
                                                mask |= YEAR;
+                                               year = n;
                                        }
                                        goto next;
                                }
@@ -698,20 +663,20 @@ parse_broken_date (date_token *tokens, int *tzone)
        
        d(printf ("\n"));
        
-       if (!(mask & (YEAR | MONTH | DAY | TIME)))
-               return 0;
-       
-       t = mktime_utc (&tm);
-       
-       /* t is now GMT of the time we want, but not offset by the timezone ... */
+       if (!(mask & (YEAR | MONTH | DAY | TIME))) {
+               if (tz != NULL)
+                       g_time_zone_unref (tz);
+               
+               return NULL;
+       }
        
-       /* this should convert the time to the GMT equiv time */
-       t -= ((offset / 100) * 60 * 60) + (offset % 100) * 60;
+       if (tz == NULL)
+               tz = g_time_zone_new_utc ();
        
-       if (tzone)
-               *tzone = offset;
+       date = g_date_time_new (tz, year, month, day, hour, min, (gdouble) sec);
+       g_time_zone_unref (tz);
        
-       return t;
+       return date;
 }
 
 #if 0
@@ -762,30 +727,23 @@ gmime_datetok_table_init (void)
 /**
  * g_mime_utils_header_decode_date:
  * @str: input date string
- * @tz_offset: (out): timezone offset
  *
- * Decodes the rfc822 date string and saves the GMT offset into
- * @tz_offset if non-NULL.
+ * Parses the rfc822 date string.
  *
- * Returns: the time_t representation of the date string specified by
- * @str or (time_t) %0 on error. If @tz_offset is non-NULL, the value
- * of the timezone offset will be stored.
+ * Returns: the #GDateTime representation of the date string specified by
+ * @str or %NULL on error.
  **/
-time_t
-g_mime_utils_header_decode_date (const char *str, int *tz_offset)
+GDateTime *
+g_mime_utils_header_decode_date (const char *str)
 {
        date_token *token, *tokens;
-       time_t date;
+       GDateTime *date;
        
-       if (!(tokens = datetok (str))) {
-               if (tz_offset)
-                       *tz_offset = 0;
-               
-               return (time_t) 0;
-       }
+       if (!(tokens = datetok (str)))
+               return NULL;
        
-       if (!(date = parse_rfc822_date (tokens, tz_offset)))
-               date = parse_broken_date (tokens, tz_offset);
+       if (!(date = parse_rfc822_date (tokens)))
+               date = parse_broken_date (tokens);
        
        /* cleanup */
        while (tokens) {
diff --git a/gmime/gmime-utils.h b/gmime/gmime-utils.h
index b624b03..8bcfc1f 100644
--- a/gmime/gmime-utils.h
+++ b/gmime/gmime-utils.h
@@ -51,8 +51,8 @@ struct _GMimeReferences {
 };
 
 
-time_t g_mime_utils_header_decode_date (const char *str, int *tz_offset);
-char  *g_mime_utils_header_format_date (time_t date, int tz_offset);
+GDateTime *g_mime_utils_header_decode_date (const char *str);
+char *g_mime_utils_header_format_date (GDateTime *date);
 
 char *g_mime_utils_generate_message_id (const char *fqdn);
 
diff --git a/tests/test-mbox.c b/tests/test-mbox.c
index 1367031..e17ebff 100644
--- a/tests/test-mbox.c
+++ b/tests/test-mbox.c
@@ -109,9 +109,8 @@ test_parser (GMimeParser *parser, GMimeStream *mbox, GMimeStream *summary)
        char *marker, *buf;
        const char *subject;
        GMimeObject *body;
-       int tz_offset;
+       GDateTime *date;
        int nmsg = 0;
-       time_t date;
        
        while (!g_mime_parser_eos (parser)) {
                message_begin = g_mime_parser_tell (parser);
@@ -127,7 +126,7 @@ test_parser (GMimeParser *parser, GMimeStream *mbox, GMimeStream *summary)
                                      message_begin, message_end);
                g_mime_stream_printf (summary, "header offsets: %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT "\n",
                                      headers_begin, headers_end);
-
+               
                marker_offset = g_mime_parser_get_mbox_marker_offset (parser);
                marker = g_mime_parser_get_mbox_marker (parser);
                g_mime_stream_printf (summary, "%s\n", marker);
@@ -150,9 +149,14 @@ test_parser (GMimeParser *parser, GMimeStream *mbox, GMimeStream *summary)
                        subject = "";
                g_mime_stream_printf (summary, "Subject: %s\n", subject);
                
-               g_mime_message_get_date (message, &date, &tz_offset);
-               buf = g_mime_utils_header_format_date (date, tz_offset);
+               if (!(date = g_mime_message_get_date (message))) {
+                       date = g_date_time_new_from_unix_utc (0);
+               } else {
+                       g_date_time_ref (date);
+               }
+               buf = g_mime_utils_header_format_date (date);
                g_mime_stream_printf (summary, "Date: %s\n", buf);
+               g_date_time_unref (date);
                g_free (buf);
                
                body = g_mime_message_get_mime_part (message);
diff --git a/tests/test-mime.c b/tests/test-mime.c
index 537ea88..cc42484 100644
--- a/tests/test-mime.c
+++ b/tests/test-mime.c
@@ -344,26 +344,43 @@ static struct {
 static void
 test_date_parser (void)
 {
+       GDateTime *date;
        Exception *ex;
-       time_t date;
-       int tzone;
+       int tz_offset;
+       GTimeSpan tz;
+       time_t time;
        char *buf;
+       int sign;
        guint i;
        
        for (i = 0; i < G_N_ELEMENTS (dates); i++) {
                testsuite_check ("Date: '%s'", dates[i].in);
                try {
-                       date = g_mime_utils_header_decode_date (dates[i].in, &tzone);
+                       if (!(date = g_mime_utils_header_decode_date (dates[i].in))) {
+                               if (dates[i].date != 0)
+                                       throw (exception_new ("failed to parse date: %s", dates[i].in));
+                               continue;
+                       }
+                       
+                       time = (time_t) g_date_time_to_unix (date);
+                       tz = g_date_time_get_utc_offset (date);
+                       
+                       sign = tz < 0 ? -1 : 1;
+                       tz *= sign;
+                       
+                       tz_offset = 100 * (tz / G_TIME_SPAN_HOUR);
+                       tz_offset += (tz % G_TIME_SPAN_HOUR) / G_TIME_SPAN_MINUTE;
+                       tz_offset *= sign;
                        
-                       if (date != dates[i].date)
-                               throw (exception_new ("time_t's do not match"));
+                       if (time != dates[i].date)
+                               throw (exception_new ("time_t's do not match: %ld vs %ld", time, 
dates[i].date));
                        
-                       if (tzone != dates[i].tzone)
+                       if (tz_offset != dates[i].tzone)
                                throw (exception_new ("timezones do not match"));
                        
-                       buf = g_mime_utils_header_format_date (date, tzone);
+                       buf = g_mime_utils_header_format_date (date);
                        if (strcmp (dates[i].out, buf) != 0) {
-                               ex = exception_new ("date strings do not match: %s", buf);
+                               ex = exception_new ("date strings do not match: %s vs %s", buf, dates[i].out);
                                g_free (buf);
                                throw (ex);
                        }
@@ -372,8 +389,7 @@ test_date_parser (void)
                        
                        testsuite_check_passed ();
                } catch (ex) {
-                       testsuite_check_failed ("Date: '%s': %s", dates[i].in,
-                                               ex->message);
+                       testsuite_check_failed ("Date: '%s': %s", dates[i].in, ex->message);
                } finally;
        }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]