|
Packit Service |
ca3877 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
|
Packit Service |
ca3877 |
/*
|
|
Packit Service |
ca3877 |
* soup-date.c: Date/time handling
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Copyright (C) 2005, Novell, Inc.
|
|
Packit Service |
ca3877 |
* Copyright (C) 2007, Red Hat, Inc.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
ca3877 |
#include <config.h>
|
|
Packit Service |
ca3877 |
#endif
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#include <stdlib.h>
|
|
Packit Service |
ca3877 |
#include <string.h>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#include "soup-date.h"
|
|
Packit Service |
ca3877 |
#include "soup.h"
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupDate:
|
|
Packit Service |
ca3877 |
* @year: the year, 1 to 9999
|
|
Packit Service |
ca3877 |
* @month: the month, 1 to 12
|
|
Packit Service |
ca3877 |
* @day: day of the month, 1 to 31
|
|
Packit Service |
ca3877 |
* @hour: hour of the day, 0 to 23
|
|
Packit Service |
ca3877 |
* @minute: minute, 0 to 59
|
|
Packit Service |
ca3877 |
* @second: second, 0 to 59 (or up to 61 in the case of leap seconds)
|
|
Packit Service |
ca3877 |
* @utc: %TRUE if the date is in UTC
|
|
Packit Service |
ca3877 |
* @offset: offset from UTC
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
* A date and time. The date is assumed to be in the (proleptic)
|
|
Packit Service |
ca3877 |
* Gregorian calendar. The time is in UTC if @utc is %TRUE. Otherwise,
|
|
Packit Service |
ca3877 |
* the time is a local time, and @offset gives the offset from UTC in
|
|
Packit Service |
ca3877 |
* minutes (such that adding @offset to the time would give the
|
|
Packit Service |
ca3877 |
* correct UTC time). If @utc is %FALSE and @offset is 0, then the
|
|
Packit Service |
ca3877 |
* %SoupDate represents a "floating" time with no associated timezone
|
|
Packit Service |
ca3877 |
* information.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Do not internationalize */
|
|
Packit Service |
ca3877 |
static const char *const months[] = {
|
|
Packit Service |
ca3877 |
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
Packit Service |
ca3877 |
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Do not internationalize */
|
|
Packit Service |
ca3877 |
static const char *const days[] = {
|
|
Packit Service |
ca3877 |
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static const int nonleap_days_in_month[] = {
|
|
Packit Service |
ca3877 |
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static const int nonleap_days_before[] = {
|
|
Packit Service |
ca3877 |
0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
|
|
Packit Service |
ca3877 |
};
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static inline gboolean
|
|
Packit Service |
ca3877 |
is_leap_year (int year)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Computes the number of days since proleptic Gregorian 0000-12-31.
|
|
Packit Service |
ca3877 |
* (That is, 0001-01-01 is "1", and 1970-01-01 is 719163.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
static int
|
|
Packit Service |
ca3877 |
rata_die_day (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
int day;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
day = (date->year - 1) * 365 + ((date->year - 1) / 4) -
|
|
Packit Service |
ca3877 |
((date->year - 1) / 100) + ((date->year - 1) / 400);
|
|
Packit Service |
ca3877 |
day += nonleap_days_before[date->month] + date->day;
|
|
Packit Service |
ca3877 |
if (is_leap_year (date->year) && date->month > 2)
|
|
Packit Service |
ca3877 |
day++;
|
|
Packit Service |
ca3877 |
return day;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#define TIME_T_EPOCH_RATA_DIE_DAY 719163
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static inline int
|
|
Packit Service |
ca3877 |
days_in_month (int month, int year)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (month == 2 && is_leap_year (year))
|
|
Packit Service |
ca3877 |
return 29;
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
return nonleap_days_in_month[month];
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_DEFINE_BOXED_TYPE (SoupDate, soup_date, soup_date_copy, soup_date_free)
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
soup_date_fixup (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
/* We only correct date->second if it's negative or too high
|
|
Packit Service |
ca3877 |
* to be a leap second.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
if (date->second < 0 || date->second > 61) {
|
|
Packit Service |
ca3877 |
date->minute += date->second / 60;
|
|
Packit Service |
ca3877 |
date->second %= 60;
|
|
Packit Service |
ca3877 |
if (date->second < 0)
|
|
Packit Service |
ca3877 |
date->second += 60;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (date->minute < 0 || date->minute > 59) {
|
|
Packit Service |
ca3877 |
date->hour += date->minute / 60;
|
|
Packit Service |
ca3877 |
date->minute %= 60;
|
|
Packit Service |
ca3877 |
if (date->minute < 0)
|
|
Packit Service |
ca3877 |
date->minute += 60;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (date->hour < 0 || date->hour > 23) {
|
|
Packit Service |
ca3877 |
date->day += date->hour / 24;
|
|
Packit Service |
ca3877 |
date->hour %= 24;
|
|
Packit Service |
ca3877 |
if (date->hour < 0)
|
|
Packit Service |
ca3877 |
date->hour += 24;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Have to make sure month is valid before we can look at the
|
|
Packit Service |
ca3877 |
* day.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
if (date->month < 1 || date->month > 12) {
|
|
Packit Service |
ca3877 |
date->year += ((date->month - 1) / 12) + 1;
|
|
Packit Service |
ca3877 |
date->month = ((date->month - 1) % 12) + 1;
|
|
Packit Service |
ca3877 |
if (date->month < 1)
|
|
Packit Service |
ca3877 |
date->month += 12;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (date->day < 0) {
|
|
Packit Service |
ca3877 |
while (date->day < 0) {
|
|
Packit Service |
ca3877 |
if (date->month == 1) {
|
|
Packit Service |
ca3877 |
date->month = 12;
|
|
Packit Service |
ca3877 |
date->year--;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
date->month--;
|
|
Packit Service |
ca3877 |
date->day += days_in_month (date->month, date->year);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
while (date->day > days_in_month (date->month, date->year)) {
|
|
Packit Service |
ca3877 |
date->day -= days_in_month (date->month, date->year);
|
|
Packit Service |
ca3877 |
if (date->month == 12) {
|
|
Packit Service |
ca3877 |
date->month = 1;
|
|
Packit Service |
ca3877 |
date->year++;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
date->month++;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_new:
|
|
Packit Service |
ca3877 |
* @year: the year (1-9999)
|
|
Packit Service |
ca3877 |
* @month: the month (1-12)
|
|
Packit Service |
ca3877 |
* @day: the day of the month (1-31, as appropriate for @month)
|
|
Packit Service |
ca3877 |
* @hour: the hour (0-23)
|
|
Packit Service |
ca3877 |
* @minute: the minute (0-59)
|
|
Packit Service |
ca3877 |
* @second: the second (0-59, or up to 61 for leap seconds)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a #SoupDate representing the indicated time, UTC.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: a new #SoupDate
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupDate *
|
|
Packit Service |
ca3877 |
soup_date_new (int year, int month, int day,
|
|
Packit Service |
ca3877 |
int hour, int minute, int second)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupDate *date = g_slice_new (SoupDate);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
date->year = year;
|
|
Packit Service |
ca3877 |
date->month = month;
|
|
Packit Service |
ca3877 |
date->day = day;
|
|
Packit Service |
ca3877 |
date->hour = hour;
|
|
Packit Service |
ca3877 |
date->minute = minute;
|
|
Packit Service |
ca3877 |
date->second = second;
|
|
Packit Service |
ca3877 |
date->utc = TRUE;
|
|
Packit Service |
ca3877 |
date->offset = 0;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return date;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_new_from_now:
|
|
Packit Service |
ca3877 |
* @offset_seconds: offset from current time
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a #SoupDate representing a time @offset_seconds after the
|
|
Packit Service |
ca3877 |
* current time (or before it, if @offset_seconds is negative). If
|
|
Packit Service |
ca3877 |
* offset_seconds is 0, returns the current time.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If @offset_seconds would indicate a time not expressible as a
|
|
Packit Service |
ca3877 |
* <type>time_t</type>, the return value will be clamped into range.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: a new #SoupDate
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupDate *
|
|
Packit Service |
ca3877 |
soup_date_new_from_now (int offset_seconds)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
time_t now = time (NULL);
|
|
Packit Service |
ca3877 |
time_t then = now + offset_seconds;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (sizeof (time_t) == 4) {
|
|
Packit Service |
ca3877 |
if (offset_seconds < 0 && then > now)
|
|
Packit Service |
ca3877 |
return soup_date_new_from_time_t (-G_MAXINT);
|
|
Packit Service |
ca3877 |
else if (offset_seconds > 0 && then < now)
|
|
Packit Service |
ca3877 |
return soup_date_new_from_time_t (G_MAXINT);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return soup_date_new_from_time_t (then);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gboolean
|
|
Packit Service |
ca3877 |
parse_iso8601_date (SoupDate *date, const char *date_string)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
gulong val;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (strlen (date_string) < 15)
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
if (date_string[4] == '-' &&
|
|
Packit Service |
ca3877 |
date_string[7] == '-' &&
|
|
Packit Service |
ca3877 |
date_string[10] == 'T') {
|
|
Packit Service |
ca3877 |
/* YYYY-MM-DD */
|
|
Packit Service |
ca3877 |
date->year = atoi (date_string);
|
|
Packit Service |
ca3877 |
date->month = atoi (date_string + 5);
|
|
Packit Service |
ca3877 |
date->day = atoi (date_string + 8);
|
|
Packit Service |
ca3877 |
date_string += 11;
|
|
Packit Service |
ca3877 |
} else if (date_string[8] == 'T') {
|
|
Packit Service |
ca3877 |
/* YYYYMMDD */
|
|
Packit Service |
ca3877 |
val = atoi (date_string);
|
|
Packit Service |
ca3877 |
date->year = val / 10000;
|
|
Packit Service |
ca3877 |
date->month = (val % 10000) / 100;
|
|
Packit Service |
ca3877 |
date->day = val % 100;
|
|
Packit Service |
ca3877 |
date_string += 9;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (strlen (date_string) >= 8 &&
|
|
Packit Service |
ca3877 |
date_string[2] == ':' && date_string[5] == ':') {
|
|
Packit Service |
ca3877 |
/* HH:MM:SS */
|
|
Packit Service |
ca3877 |
date->hour = atoi (date_string);
|
|
Packit Service |
ca3877 |
date->minute = atoi (date_string + 3);
|
|
Packit Service |
ca3877 |
date->second = atoi (date_string + 6);
|
|
Packit Service |
ca3877 |
date_string += 8;
|
|
Packit Service |
ca3877 |
} else if (strlen (date_string) >= 6) {
|
|
Packit Service |
ca3877 |
/* HHMMSS */
|
|
Packit Service |
ca3877 |
val = strtoul (date_string, (char **)&date_string, 10);
|
|
Packit Service |
ca3877 |
date->hour = val / 10000;
|
|
Packit Service |
ca3877 |
date->minute = (val % 10000) / 100;
|
|
Packit Service |
ca3877 |
date->second = val % 100;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (*date_string == '.' || *date_string == ',')
|
|
Packit Service |
ca3877 |
(void) strtoul (date_string + 1, (char **)&date_string, 10);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (*date_string == 'Z') {
|
|
Packit Service |
ca3877 |
date_string++;
|
|
Packit Service |
ca3877 |
date->utc = TRUE;
|
|
Packit Service |
ca3877 |
date->offset = 0;
|
|
Packit Service |
ca3877 |
} else if (*date_string == '+' || *date_string == '-') {
|
|
Packit Service |
ca3877 |
int sign = (*date_string == '+') ? -1 : 1;
|
|
Packit Service |
ca3877 |
val = strtoul (date_string + 1, (char **)&date_string, 10);
|
|
Packit Service |
ca3877 |
if (*date_string == ':')
|
|
Packit Service |
ca3877 |
val = 60 * val + strtoul (date_string + 1, (char **)&date_string, 10);
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
val = 60 * (val / 100) + (val % 100);
|
|
Packit Service |
ca3877 |
date->offset = sign * val;
|
|
Packit Service |
ca3877 |
date->utc = !val;
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
date->offset = 0;
|
|
Packit Service |
ca3877 |
date->utc = FALSE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return !*date_string;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static inline gboolean
|
|
Packit Service |
ca3877 |
parse_day (SoupDate *date, const char **date_string)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
char *end;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
date->day = strtoul (*date_string, &end, 10);
|
|
Packit Service |
ca3877 |
if (end == (char *)*date_string)
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
while (*end == ' ' || *end == '-')
|
|
Packit Service |
ca3877 |
end++;
|
|
Packit Service |
ca3877 |
*date_string = end;
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static inline gboolean
|
|
Packit Service |
ca3877 |
parse_month (SoupDate *date, const char **date_string)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
int i;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
for (i = 0; i < G_N_ELEMENTS (months); i++) {
|
|
Packit Service |
ca3877 |
if (!g_ascii_strncasecmp (*date_string, months[i], 3)) {
|
|
Packit Service |
ca3877 |
date->month = i + 1;
|
|
Packit Service |
ca3877 |
*date_string += 3;
|
|
Packit Service |
ca3877 |
while (**date_string == ' ' || **date_string == '-')
|
|
Packit Service |
ca3877 |
(*date_string)++;
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static inline gboolean
|
|
Packit Service |
ca3877 |
parse_year (SoupDate *date, const char **date_string)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
char *end;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
date->year = strtoul (*date_string, &end, 10);
|
|
Packit Service |
ca3877 |
if (end == (char *)*date_string)
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (end == (char *)*date_string + 2) {
|
|
Packit Service |
ca3877 |
if (date->year < 70)
|
|
Packit Service |
ca3877 |
date->year += 2000;
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
date->year += 1900;
|
|
Packit Service |
ca3877 |
} else if (end == (char *)*date_string + 3)
|
|
Packit Service |
ca3877 |
date->year += 1900;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
while (*end == ' ' || *end == '-')
|
|
Packit Service |
ca3877 |
end++;
|
|
Packit Service |
ca3877 |
*date_string = end;
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static inline gboolean
|
|
Packit Service |
ca3877 |
parse_time (SoupDate *date, const char **date_string)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
char *p, *end;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
date->hour = strtoul (*date_string, &end, 10);
|
|
Packit Service |
ca3877 |
if (end == (char *)*date_string || *end++ != ':')
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
p = end;
|
|
Packit Service |
ca3877 |
date->minute = strtoul (p, &end, 10);
|
|
Packit Service |
ca3877 |
if (end == p || *end++ != ':')
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
p = end;
|
|
Packit Service |
ca3877 |
date->second = strtoul (p, &end, 10);
|
|
Packit Service |
ca3877 |
if (end == p)
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
p = end;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
while (*p == ' ')
|
|
Packit Service |
ca3877 |
p++;
|
|
Packit Service |
ca3877 |
*date_string = p;
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static inline gboolean
|
|
Packit Service |
ca3877 |
parse_timezone (SoupDate *date, const char **date_string)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (!**date_string) {
|
|
Packit Service |
ca3877 |
date->utc = FALSE;
|
|
Packit Service |
ca3877 |
date->offset = 0;
|
|
Packit Service |
ca3877 |
} else if (**date_string == '+' || **date_string == '-') {
|
|
Packit Service |
ca3877 |
gulong val;
|
|
Packit Service |
ca3877 |
int sign = (**date_string == '+') ? -1 : 1;
|
|
Packit Service |
ca3877 |
val = strtoul (*date_string + 1, (char **)date_string, 10);
|
|
Packit Service |
ca3877 |
if (**date_string == ':')
|
|
Packit Service |
ca3877 |
val = 60 * val + strtoul (*date_string + 1, (char **)date_string, 10);
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
val = 60 * (val / 100) + (val % 100);
|
|
Packit Service |
ca3877 |
date->offset = sign * val;
|
|
Packit Service |
ca3877 |
date->utc = (sign == -1) && !val;
|
|
Packit Service |
ca3877 |
} else if (**date_string == 'Z') {
|
|
Packit Service |
ca3877 |
date->offset = 0;
|
|
Packit Service |
ca3877 |
date->utc = TRUE;
|
|
Packit Service |
ca3877 |
(*date_string)++;
|
|
Packit Service |
ca3877 |
} else if (!strcmp (*date_string, "GMT") ||
|
|
Packit Service |
ca3877 |
!strcmp (*date_string, "UTC")) {
|
|
Packit Service |
ca3877 |
date->offset = 0;
|
|
Packit Service |
ca3877 |
date->utc = TRUE;
|
|
Packit Service |
ca3877 |
(*date_string) += 3;
|
|
Packit Service |
ca3877 |
} else if (strchr ("ECMP", **date_string) &&
|
|
Packit Service |
ca3877 |
((*date_string)[1] == 'D' || (*date_string)[1] == 'S') &&
|
|
Packit Service |
ca3877 |
(*date_string)[2] == 'T') {
|
|
Packit Service |
ca3877 |
date->offset = -60 * (5 * strcspn ("ECMP", *date_string));
|
|
Packit Service |
ca3877 |
if ((*date_string)[1] == 'D')
|
|
Packit Service |
ca3877 |
date->offset += 60;
|
|
Packit Service |
ca3877 |
date->utc = FALSE;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gboolean
|
|
Packit Service |
ca3877 |
parse_textual_date (SoupDate *date, const char *date_string)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
/* If it starts with a word, it must be a weekday, which we skip */
|
|
Packit Service |
ca3877 |
if (g_ascii_isalpha (*date_string)) {
|
|
Packit Service |
ca3877 |
while (g_ascii_isalpha (*date_string))
|
|
Packit Service |
ca3877 |
date_string++;
|
|
Packit Service |
ca3877 |
if (*date_string == ',')
|
|
Packit Service |
ca3877 |
date_string++;
|
|
Packit Service |
ca3877 |
while (g_ascii_isspace (*date_string))
|
|
Packit Service |
ca3877 |
date_string++;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* If there's now another word, this must be an asctime-date */
|
|
Packit Service |
ca3877 |
if (g_ascii_isalpha (*date_string)) {
|
|
Packit Service |
ca3877 |
/* (Sun) Nov 6 08:49:37 1994 */
|
|
Packit Service |
ca3877 |
if (!parse_month (date, &date_string) ||
|
|
Packit Service |
ca3877 |
!parse_day (date, &date_string) ||
|
|
Packit Service |
ca3877 |
!parse_time (date, &date_string) ||
|
|
Packit Service |
ca3877 |
!parse_year (date, &date_string))
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* There shouldn't be a timezone, but check anyway */
|
|
Packit Service |
ca3877 |
parse_timezone (date, &date_string);
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
/* Non-asctime date, so some variation of
|
|
Packit Service |
ca3877 |
* (Sun,) 06 Nov 1994 08:49:37 GMT
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
if (!parse_day (date, &date_string) ||
|
|
Packit Service |
ca3877 |
!parse_month (date, &date_string) ||
|
|
Packit Service |
ca3877 |
!parse_year (date, &date_string) ||
|
|
Packit Service |
ca3877 |
!parse_time (date, &date_string))
|
|
Packit Service |
ca3877 |
return FALSE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* This time there *should* be a timezone, but we
|
|
Packit Service |
ca3877 |
* survive if there isn't.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
parse_timezone (date, &date_string);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* SoupDateFormat:
|
|
Packit Service |
ca3877 |
* @SOUP_DATE_HTTP: RFC 1123 format, used by the HTTP "Date" header. Eg
|
|
Packit Service |
ca3877 |
* "Sun, 06 Nov 1994 08:49:37 GMT"
|
|
Packit Service |
ca3877 |
* @SOUP_DATE_COOKIE: The format for the "Expires" timestamp in the
|
|
Packit Service |
ca3877 |
* Netscape cookie specification. Eg, "Sun, 06-Nov-1994 08:49:37 GMT".
|
|
Packit Service |
ca3877 |
* @SOUP_DATE_RFC2822: RFC 2822 format, eg "Sun, 6 Nov 1994 09:49:37 -0100"
|
|
Packit Service |
ca3877 |
* @SOUP_DATE_ISO8601_COMPACT: ISO 8601 date/time with no optional
|
|
Packit Service |
ca3877 |
* punctuation. Eg, "19941106T094937-0100".
|
|
Packit Service |
ca3877 |
* @SOUP_DATE_ISO8601_FULL: ISO 8601 date/time with all optional
|
|
Packit Service |
ca3877 |
* punctuation. Eg, "1994-11-06T09:49:37-01:00".
|
|
Packit Service |
ca3877 |
* @SOUP_DATE_ISO8601_XMLRPC: ISO 8601 date/time as used by XML-RPC.
|
|
Packit Service |
ca3877 |
* Eg, "19941106T09:49:37".
|
|
Packit Service |
ca3877 |
* @SOUP_DATE_ISO8601: An alias for @SOUP_DATE_ISO8601_FULL.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Date formats that soup_date_to_string() can use.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* @SOUP_DATE_HTTP and @SOUP_DATE_COOKIE always coerce the time to
|
|
Packit Service |
ca3877 |
* UTC. @SOUP_DATE_ISO8601_XMLRPC uses the time as given, ignoring the
|
|
Packit Service |
ca3877 |
* offset completely. @SOUP_DATE_RFC2822 and the other ISO 8601
|
|
Packit Service |
ca3877 |
* variants use the local time, appending the offset information if
|
|
Packit Service |
ca3877 |
* available.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* This enum may be extended with more values in future releases.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_new_from_string:
|
|
Packit Service |
ca3877 |
* @date_string: the date in some plausible format
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Parses @date_string and tries to extract a date from it. This
|
|
Packit Service |
ca3877 |
* recognizes all of the "HTTP-date" formats from RFC 2616, all ISO
|
|
Packit Service |
ca3877 |
* 8601 formats containing both a time and a date, RFC 2822 dates,
|
|
Packit Service |
ca3877 |
* and reasonable approximations thereof. (Eg, it is lenient about
|
|
Packit Service |
ca3877 |
* whitespace, leading "0"s, etc.)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: (nullable): a new #SoupDate, or %NULL if @date_string
|
|
Packit Service |
ca3877 |
* could not be parsed.
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupDate *
|
|
Packit Service |
ca3877 |
soup_date_new_from_string (const char *date_string)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupDate *date;
|
|
Packit Service |
ca3877 |
gboolean success;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_return_val_if_fail (date_string != NULL, NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
date = g_slice_new (SoupDate);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
while (g_ascii_isspace (*date_string))
|
|
Packit Service |
ca3877 |
date_string++;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* If it starts with a digit, it's either an ISO 8601 date, or
|
|
Packit Service |
ca3877 |
* an RFC2822 date without the optional weekday; in the later
|
|
Packit Service |
ca3877 |
* case, there will be a month name later on, so look for one
|
|
Packit Service |
ca3877 |
* of the month-start letters.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
if (g_ascii_isdigit (*date_string) &&
|
|
Packit Service |
ca3877 |
!strpbrk (date_string, "JFMASOND"))
|
|
Packit Service |
ca3877 |
success = parse_iso8601_date (date, date_string);
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
success = parse_textual_date (date, date_string);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (!success) {
|
|
Packit Service |
ca3877 |
g_slice_free (SoupDate, date);
|
|
Packit Service |
ca3877 |
return NULL;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (date->year < 1 || date->year > 9999 ||
|
|
Packit Service |
ca3877 |
date->month < 1 || date->month > 12 ||
|
|
Packit Service |
ca3877 |
date->day < 1 ||
|
|
Packit Service |
ca3877 |
date->day > days_in_month (date->month, date->year) ||
|
|
Packit Service |
ca3877 |
date->hour < 0 || date->hour > 24 ||
|
|
Packit Service |
ca3877 |
date->minute < 0 || date->minute > 59 ||
|
|
Packit Service |
ca3877 |
date->second < 0 || date->second > 61) {
|
|
Packit Service |
ca3877 |
soup_date_free (date);
|
|
Packit Service |
ca3877 |
return NULL;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
if (date->hour == 24) {
|
|
Packit Service |
ca3877 |
/* ISO8601 allows this explicitly. We allow it for
|
|
Packit Service |
ca3877 |
* other types as well just for simplicity.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
if (date->minute == 0 && date->second == 0)
|
|
Packit Service |
ca3877 |
soup_date_fixup (date);
|
|
Packit Service |
ca3877 |
else {
|
|
Packit Service |
ca3877 |
soup_date_free (date);
|
|
Packit Service |
ca3877 |
return NULL;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return date;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_new_from_time_t:
|
|
Packit Service |
ca3877 |
* @when: a <type>time_t</type>
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Creates a #SoupDate corresponding to @when
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: a new #SoupDate
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupDate *
|
|
Packit Service |
ca3877 |
soup_date_new_from_time_t (time_t when)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
struct tm tm;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#ifdef HAVE_GMTIME_R
|
|
Packit Service |
ca3877 |
gmtime_r (&when, &tm;;
|
|
Packit Service |
ca3877 |
#else
|
|
Packit Service |
ca3877 |
tm = *gmtime (&when);
|
|
Packit Service |
ca3877 |
#endif
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return soup_date_new (tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
|
Packit Service |
ca3877 |
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static const char *
|
|
Packit Service |
ca3877 |
soup_date_weekday (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
/* Proleptic Gregorian 0001-01-01 was a Monday, which
|
|
Packit Service |
ca3877 |
* corresponds to 1 in the days[] array.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
return days[rata_die_day (date) % 7];
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_to_string:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
* @format: the format to generate the date in
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Converts @date to a string in the format described by @format.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: @date as a string
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
char *
|
|
Packit Service |
ca3877 |
soup_date_to_string (SoupDate *date, SoupDateFormat format)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_return_val_if_fail (date != NULL, NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (format == SOUP_DATE_HTTP || format == SOUP_DATE_COOKIE) {
|
|
Packit Service |
ca3877 |
/* HTTP and COOKIE formats require UTC timestamp, so coerce
|
|
Packit Service |
ca3877 |
* @date if it's non-UTC.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
SoupDate utcdate;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (date->offset != 0) {
|
|
Packit Service |
ca3877 |
memcpy (&utcdate, date, sizeof (SoupDate));
|
|
Packit Service |
ca3877 |
utcdate.minute += utcdate.offset;
|
|
Packit Service |
ca3877 |
utcdate.offset = 0;
|
|
Packit Service |
ca3877 |
utcdate.utc = TRUE;
|
|
Packit Service |
ca3877 |
soup_date_fixup (&utcdate);
|
|
Packit Service |
ca3877 |
date = &utcdate;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
switch (format) {
|
|
Packit Service |
ca3877 |
case SOUP_DATE_HTTP:
|
|
Packit Service |
ca3877 |
/* "Sun, 06 Nov 1994 08:49:37 GMT" */
|
|
Packit Service |
ca3877 |
return g_strdup_printf (
|
|
Packit Service |
ca3877 |
"%s, %02d %s %04d %02d:%02d:%02d GMT",
|
|
Packit Service |
ca3877 |
soup_date_weekday (date), date->day,
|
|
Packit Service |
ca3877 |
months[date->month - 1], date->year,
|
|
Packit Service |
ca3877 |
date->hour, date->minute, date->second);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
case SOUP_DATE_COOKIE:
|
|
Packit Service |
ca3877 |
/* "Sun, 06-Nov-1994 08:49:37 GMT" */
|
|
Packit Service |
ca3877 |
return g_strdup_printf (
|
|
Packit Service |
ca3877 |
"%s, %02d-%s-%04d %02d:%02d:%02d GMT",
|
|
Packit Service |
ca3877 |
soup_date_weekday (date), date->day,
|
|
Packit Service |
ca3877 |
months[date->month - 1], date->year,
|
|
Packit Service |
ca3877 |
date->hour, date->minute, date->second);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
default:
|
|
Packit Service |
ca3877 |
g_return_val_if_reached (NULL);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
} else if (format == SOUP_DATE_ISO8601_XMLRPC) {
|
|
Packit Service |
ca3877 |
/* Always "floating", ignore offset */
|
|
Packit Service |
ca3877 |
return g_strdup_printf ("%04d%02d%02dT%02d:%02d:%02d",
|
|
Packit Service |
ca3877 |
date->year, date->month, date->day,
|
|
Packit Service |
ca3877 |
date->hour, date->minute, date->second);
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
int hour_offset, minute_offset;
|
|
Packit Service |
ca3877 |
char zone[8], sign;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* For other ISO8601 formats or RFC2822, use the
|
|
Packit Service |
ca3877 |
* offset given in @date. For ISO8601 formats, use "Z"
|
|
Packit Service |
ca3877 |
* for UTC, +-offset for non-UTC, and nothing for
|
|
Packit Service |
ca3877 |
* floating. For RFC2822, use +-offset for UTC or
|
|
Packit Service |
ca3877 |
* non-UTC, and -0000 for floating.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
hour_offset = abs (date->offset) / 60;
|
|
Packit Service |
ca3877 |
minute_offset = abs (date->offset) - hour_offset * 60;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
switch (format) {
|
|
Packit Service |
ca3877 |
case SOUP_DATE_ISO8601_COMPACT:
|
|
Packit Service |
ca3877 |
/* "19941106T084937[zone]" */
|
|
Packit Service |
ca3877 |
if (date->utc)
|
|
Packit Service |
ca3877 |
strcpy (zone, "Z");
|
|
Packit Service |
ca3877 |
else if (date->offset) {
|
|
Packit Service |
ca3877 |
g_snprintf (zone, sizeof (zone), "%c%02d%02d",
|
|
Packit Service |
ca3877 |
date->offset > 0 ? '-' : '+',
|
|
Packit Service |
ca3877 |
hour_offset, minute_offset);
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
*zone = '\0';
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return g_strdup_printf (
|
|
Packit Service |
ca3877 |
"%04d%02d%02dT%02d%02d%02d%s",
|
|
Packit Service |
ca3877 |
date->year, date->month, date->day,
|
|
Packit Service |
ca3877 |
date->hour, date->minute, date->second,
|
|
Packit Service |
ca3877 |
zone);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
case SOUP_DATE_ISO8601_FULL:
|
|
Packit Service |
ca3877 |
/* "1994-11-06T08:49:37[zone]" */
|
|
Packit Service |
ca3877 |
if (date->utc)
|
|
Packit Service |
ca3877 |
strcpy (zone, "Z");
|
|
Packit Service |
ca3877 |
else if (date->offset) {
|
|
Packit Service |
ca3877 |
g_snprintf (zone, sizeof (zone), "%c%02d:%02d",
|
|
Packit Service |
ca3877 |
date->offset > 0 ? '-' : '+',
|
|
Packit Service |
ca3877 |
hour_offset, minute_offset);
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
*zone = '\0';
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return g_strdup_printf (
|
|
Packit Service |
ca3877 |
"%04d-%02d-%02dT%02d:%02d:%02d%s",
|
|
Packit Service |
ca3877 |
date->year, date->month, date->day,
|
|
Packit Service |
ca3877 |
date->hour, date->minute, date->second,
|
|
Packit Service |
ca3877 |
zone);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
case SOUP_DATE_RFC2822:
|
|
Packit Service |
ca3877 |
/* "Sun, 6 Nov 1994 09:49:37 -0100" */
|
|
Packit Service |
ca3877 |
if (date->offset)
|
|
Packit Service |
ca3877 |
sign = (date->offset > 0) ? '-' : '+';
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
sign = date->utc ? '+' : '-';
|
|
Packit Service |
ca3877 |
return g_strdup_printf (
|
|
Packit Service |
ca3877 |
"%s, %d %s %04d %02d:%02d:%02d %c%02d%02d",
|
|
Packit Service |
ca3877 |
soup_date_weekday (date), date->day,
|
|
Packit Service |
ca3877 |
months[date->month - 1], date->year,
|
|
Packit Service |
ca3877 |
date->hour, date->minute, date->second,
|
|
Packit Service |
ca3877 |
sign, hour_offset, minute_offset);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
default:
|
|
Packit Service |
ca3877 |
return NULL;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_to_time_t:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Converts @date to a <type>time_t</type>.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* If @date is not representable as a <type>time_t</type>, it will be
|
|
Packit Service |
ca3877 |
* clamped into range. (In particular, some HTTP cookies have
|
|
Packit Service |
ca3877 |
* expiration dates after "Y2.038k" (2038-01-19T03:14:07Z).)
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: @date as a <type>time_t</type>
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
time_t
|
|
Packit Service |
ca3877 |
soup_date_to_time_t (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
time_t tt;
|
|
Packit Service |
ca3877 |
GTimeVal val;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_return_val_if_fail (date != NULL, 0);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* FIXME: offset, etc */
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (date->year < 1970)
|
|
Packit Service |
ca3877 |
return 0;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* If the year is later than 2038, we're guaranteed to
|
|
Packit Service |
ca3877 |
* overflow a 32-bit time_t. (If it's exactly 2038, we'll
|
|
Packit Service |
ca3877 |
* *probably* overflow, but only by a little, and it's easiest
|
|
Packit Service |
ca3877 |
* to test that at the end by seeing if the result has turned
|
|
Packit Service |
ca3877 |
* negative.)
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
if (sizeof (time_t) == 4 && date->year > 2038)
|
|
Packit Service |
ca3877 |
return (time_t)0x7fffffff;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
soup_date_to_timeval (date, &val;;
|
|
Packit Service |
ca3877 |
tt = val.tv_sec;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (sizeof (time_t) == 4 && tt < 0)
|
|
Packit Service |
ca3877 |
return (time_t)0x7fffffff;
|
|
Packit Service |
ca3877 |
return tt;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_to_timeval:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
* @time: (out): a #GTimeVal structure in which to store the converted time.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Converts @date to a #GTimeVal.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.24
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_date_to_timeval (SoupDate *date, GTimeVal *time)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_return_if_fail (date != NULL);
|
|
Packit Service |
ca3877 |
g_return_if_fail (time != NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* FIXME: offset, etc */
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
time->tv_sec = rata_die_day (date) - TIME_T_EPOCH_RATA_DIE_DAY;
|
|
Packit Service |
ca3877 |
time->tv_sec = ((((time->tv_sec * 24) + date->hour) * 60) + date->minute) * 60 + date->second;
|
|
Packit Service |
ca3877 |
time->tv_usec = 0;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_is_past:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Determines if @date is in the past.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: %TRUE if @date is in the past
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.24
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gboolean
|
|
Packit Service |
ca3877 |
soup_date_is_past (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_return_val_if_fail (date != NULL, TRUE);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* optimization */
|
|
Packit Service |
ca3877 |
if (date->year < 2010)
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return soup_date_to_time_t (date) < time (NULL);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_get_year:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets @date's year.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: @date's year
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
int
|
|
Packit Service |
ca3877 |
soup_date_get_year (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return date->year;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_get_month:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets @date's month.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: @date's month
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
int
|
|
Packit Service |
ca3877 |
soup_date_get_month (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return date->month;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_get_day:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets @date's day.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: @date's day
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
int
|
|
Packit Service |
ca3877 |
soup_date_get_day (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return date->day;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_get_hour:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets @date's hour.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: @date's hour
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
int
|
|
Packit Service |
ca3877 |
soup_date_get_hour (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return date->hour;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_get_minute:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets @date's minute.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: @date's minute
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
int
|
|
Packit Service |
ca3877 |
soup_date_get_minute (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return date->minute;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_get_second:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets @date's second.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: @date's second
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
int
|
|
Packit Service |
ca3877 |
soup_date_get_second (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return date->second;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_get_utc:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets @date's UTC flag
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: %TRUE if @date is UTC.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
gboolean
|
|
Packit Service |
ca3877 |
soup_date_get_utc (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return date->utc;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_get_offset:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Gets @date's offset from UTC.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Return value: @date's offset from UTC. If soup_date_get_utc()
|
|
Packit Service |
ca3877 |
* returns %FALSE but soup_date_get_offset() returns 0, that means the
|
|
Packit Service |
ca3877 |
* date is a "floating" time with no associated offset information.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.32
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
int
|
|
Packit Service |
ca3877 |
soup_date_get_offset (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return date->offset;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_copy:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Copies @date.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.24
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
SoupDate *
|
|
Packit Service |
ca3877 |
soup_date_copy (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupDate *copy;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_return_val_if_fail (date != NULL, NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
copy = g_slice_new (SoupDate);
|
|
Packit Service |
ca3877 |
memcpy (copy, date, sizeof (SoupDate));
|
|
Packit Service |
ca3877 |
return copy;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/**
|
|
Packit Service |
ca3877 |
* soup_date_free:
|
|
Packit Service |
ca3877 |
* @date: a #SoupDate
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Frees @date.
|
|
Packit Service |
ca3877 |
*
|
|
Packit Service |
ca3877 |
* Since: 2.24
|
|
Packit Service |
ca3877 |
**/
|
|
Packit Service |
ca3877 |
void
|
|
Packit Service |
ca3877 |
soup_date_free (SoupDate *date)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
g_return_if_fail (date != NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_slice_free (SoupDate, date);
|
|
Packit Service |
ca3877 |
}
|