cvsimport
[beagle.git] / libbeagle / beagle / beagle-timestamp.c
blob7616f7881bae43fcfc49cc8cec620c0afa0bf8ff
1 /*
2 * beagle-timestamp.c
4 * Copyright (C) 2005 Novell, Inc.
6 */
8 /*
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
28 #include "beagle-timestamp.h"
29 #include "beagle-private.h"
30 #include <stdio.h>
31 #include <time.h>
32 #include <stdlib.h>
34 struct _BeagleTimestamp {
35 int year, month, day;
37 int hour, minute, second;
39 int ticks;
41 int tz_hour, tz_minute;
44 static BeagleTimestamp *
45 beagle_timestamp_new (void)
47 BeagleTimestamp *timestamp;
49 timestamp = g_new0 (BeagleTimestamp, 1);
51 return timestamp;
54 /**
55 * beagle_timestamp_new_from_string:
56 * @str: a string
58 * Creates a newly allocated #BeagleTimestamp from the given string. The string should be of the following format, "2005-06-23T10:05:11.0000000+01:00".
60 * Return value: the newly allocated #BeagleTimestamp.
61 **/
62 BeagleTimestamp *
63 beagle_timestamp_new_from_string (const char *str)
65 BeagleTimestamp *timestamp;
66 int consumed;
68 timestamp = beagle_timestamp_new ();
70 consumed = sscanf (str, "%04d-%02d-%02dT%02d:%02d:%02d.%07d%03d:%02d",
71 &timestamp->year, &timestamp->month, &timestamp->day,
72 &timestamp->hour, &timestamp->minute, &timestamp->second,
73 &timestamp->ticks, &timestamp->tz_hour, &timestamp->tz_minute);
75 if (consumed != 9) {
76 beagle_timestamp_free (timestamp);
77 return NULL;
81 return timestamp;
84 /**
85 * beagle_timestamp_new_from_unix_time:
86 * @time: a #time_t
88 * Creates a newly allocated #BeagleTimestamp from @time.
90 * Return value: the newly created #BeagleTimestamp.
91 **/
92 BeagleTimestamp *
93 beagle_timestamp_new_from_unix_time (time_t time)
95 BeagleTimestamp *timestamp;
96 struct tm *result;
97 gboolean before_utc;
98 int offset_mins, tz_hour, tz_min;
100 /* Send everything in localtime since XmlSerializer .Net-1.0 likes that.
101 * FIXED: To be changed back to gmtime() in .Net-2.0 era.
103 result = localtime (&time);
105 timestamp = beagle_timestamp_new ();
107 timestamp->year = result->tm_year + 1900;
108 timestamp->month = result->tm_mon + 1;
109 timestamp->day = result->tm_mday;
111 timestamp->hour = result->tm_hour;
112 timestamp->minute = result->tm_min;
113 timestamp->second = result->tm_sec;
115 /* Compute timezone offset. */
116 time = 0;
117 result = localtime (&time);
118 before_utc = (result->tm_mday == 1);
120 offset_mins = 60 * result->tm_hour + result->tm_min;
121 if (before_utc == FALSE)
122 offset_mins = 1440 - offset_mins; /* 1440 = mins in 1 day */
124 tz_hour = offset_mins/60;
125 tz_min = offset_mins % 60;
126 if (before_utc == FALSE)
127 tz_hour = -tz_hour;
129 timestamp->tz_hour = tz_hour;
130 timestamp->tz_minute = tz_min;
132 return timestamp;
136 * beagle_timestamp_free:
137 * @timestamp: a #BeagleTimestamp
139 * Frees the memory allocated by the given #BeagleTimestamp.
141 void
142 beagle_timestamp_free (BeagleTimestamp *timestamp)
144 g_free (timestamp);
147 /* I love you, UNIX */
148 static time_t
149 give_me_a_time_t_that_is_utc (struct tm *tm) {
150 time_t ret;
151 char *tz;
153 tz = getenv("TZ");
154 setenv("TZ", "", 1);
155 tzset();
156 ret = mktime(tm);
157 if (tz)
158 setenv("TZ", tz, 1);
159 else
160 unsetenv("TZ");
161 tzset();
162 return ret;
166 * beagle_timestamp_to_unix_time:
167 * @timestamp: a #BeagleTimestamp
168 * @time: a #time_t
170 * Converts the given #BeagleTimestamp to a unix #time_t.
172 * Return value: %TRUE on success and otherwise %FALSE.
174 gboolean
175 beagle_timestamp_to_unix_time (BeagleTimestamp *timestamp, time_t *time)
177 time_t result, tz;
178 struct tm tm_time;
180 /* We special-case the timestamp "epoch" and use the unix epoch */
181 if (timestamp->year == 0 && timestamp->month == 0 && timestamp->day == 0 &&
182 timestamp->hour == 0 && timestamp->minute == 0 && timestamp->second == 0 &&
183 timestamp->ticks == 0 && timestamp->tz_hour == 0 && timestamp->tz_minute == 0) {
184 *time = 0;
185 return TRUE;
188 if (timestamp->year < 1970 || timestamp->year > 2038) {
189 return FALSE;
192 tm_time.tm_year = timestamp->year - 1900;
193 tm_time.tm_mon = timestamp->month - 1;
194 tm_time.tm_mday = timestamp->day;
195 tm_time.tm_hour = timestamp->hour;
196 tm_time.tm_min = timestamp->minute;
197 tm_time.tm_sec = timestamp->second;
198 tm_time.tm_isdst = -1;
200 result = give_me_a_time_t_that_is_utc (&tm_time);
202 if (result == -1)
203 return FALSE;
205 /* Add timezone */
206 if (timestamp->tz_hour > 0)
207 tz = timestamp->tz_hour * 60 + timestamp->tz_minute;
208 else
209 tz = timestamp->tz_hour *60 - timestamp->tz_minute;
211 tz *= 60;
213 result += tz;
215 /* Check for overflow */
216 if (result < 0)
217 return FALSE;
219 *time = result;
221 return TRUE;
224 char *
225 _beagle_timestamp_to_string (BeagleTimestamp *timestamp)
227 return g_strdup_printf ("%04d-%02d-%02dT%02d:%02d:%02d.%07d%+03d:%02d",
228 timestamp->year, timestamp->month, timestamp->day,
229 timestamp->hour, timestamp->minute, timestamp->second,
230 timestamp->ticks, timestamp->tz_hour, timestamp->tz_minute);
234 char *
235 _beagle_timestamp_get_start (void)
237 return NULL;