2 * Copyright (C) 2004-2006, Eric Lund
3 * http://www.mvpmc.org/
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * timestamp.c - functions to manage MythTV timestamps. Primarily,
22 * these allocate timestamps and convert between string
23 * and cmyth_timestamp_t and between time_t and
26 #include <sys/types.h>
35 #include <cmyth_local.h>
40 * cmyth_timestamp_create(void)
46 * Create a timestamp structure and return a pointer to the structure.
50 * Success: A non-NULL cmyth_timestamp_t (this type is a pointer)
52 * Failure: A NULL cmyth_timestamp_t
55 cmyth_timestamp_create(void)
57 cmyth_timestamp_t ret = ref_alloc(sizeof(*ret));
59 cmyth_dbg(CMYTH_DBG_DEBUG, "%s\n", __FUNCTION__);
63 ret->timestamp_year = 0;
64 ret->timestamp_month = 0;
65 ret->timestamp_day = 0;
66 ret->timestamp_hour = 0;
67 ret->timestamp_minute = 0;
68 ret->timestamp_second = 0;
69 ret->timestamp_isdst = 0;
74 * cmyth_timestamp_from_string(char *str)
80 * Create and fill out a timestamp structure using the string 'str'.
81 * The string must be a timestamp of the forn:
87 * Success: A timestamp structure (this is a pointer type)
92 cmyth_timestamp_from_string(char *str)
94 cmyth_timestamp_t ret;
105 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL string\n", __FUNCTION__);
109 ret = cmyth_timestamp_create();
111 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp\n",
115 if (strlen(str) != CMYTH_TIMESTAMP_LEN) {
117 if (strlen(str) != CMYTH_DATESTAMP_LEN) {
118 cmyth_dbg(CMYTH_DBG_ERROR,
119 "%s: string is not a timestamp '%s'\n",
125 if ((datetime == 1) &&
126 ((str[4] != '-') || (str[7] != '-') || (str[10] != 'T') ||
127 (str[13] != ':') || (str[16] != ':'))) {
128 cmyth_dbg(CMYTH_DBG_ERROR, "%s: string is badly formed '%s'\n",
132 if ((datetime == 0) &&
133 ((str[4] != '-') || (str[7] != '-'))) {
134 cmyth_dbg(CMYTH_DBG_ERROR, "%s: string is badly formed '%s'\n",
147 i < (datetime ? CMYTH_TIMESTAMP_LEN : CMYTH_DATESTAMP_LEN);
149 if (str[i] && !isdigit(str[i])) {
150 cmyth_dbg(CMYTH_DBG_ERROR,
151 "%s: expected numeral at '%s'[%d]\n",
152 __FUNCTION__, str, i);
156 ret->timestamp_year = atoi(yyyy);
157 ret->timestamp_month = atoi(MM);
158 if (ret->timestamp_month > 12) {
159 cmyth_dbg(CMYTH_DBG_ERROR, "%s: month value too big'%s'\n",
163 ret->timestamp_day = atoi(dd);
164 if (ret->timestamp_day > 31) {
165 cmyth_dbg(CMYTH_DBG_ERROR, "%s: day value too big'%s'\n",
173 ret->timestamp_hour = atoi(hh);
174 if (ret->timestamp_hour > 23) {
175 cmyth_dbg(CMYTH_DBG_ERROR, "%s: hour value too big'%s'\n",
179 ret->timestamp_minute = atoi(mm);
180 if (ret->timestamp_minute > 59) {
181 cmyth_dbg(CMYTH_DBG_ERROR, "%s: minute value too big'%s'\n",
185 ret->timestamp_second = atoi(ss);
186 if (ret->timestamp_second > 59) {
187 cmyth_dbg(CMYTH_DBG_ERROR, "%s: second value too big'%s'\n",
199 cmyth_timestamp_from_tm(struct tm * tm_datetime)
201 cmyth_timestamp_t ret;
202 ret = cmyth_timestamp_create();
204 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp\n",
209 ret->timestamp_year = tm_datetime->tm_year + 1900;
210 ret->timestamp_month = tm_datetime->tm_mon + 1;
211 ret->timestamp_day = tm_datetime->tm_mday;
212 ret->timestamp_hour = tm_datetime->tm_hour;
213 ret->timestamp_minute = tm_datetime->tm_min;
214 ret->timestamp_second = tm_datetime->tm_sec;
215 ret->timestamp_isdst = tm_datetime->tm_isdst;
220 * cmyth_timestamp_from_unixtime(time_t l)
226 * Create and fill out a timestamp structure using the time_t 'l'.
230 * Success: cmyth_timestamp_t object
235 cmyth_timestamp_from_unixtime(time_t l)
237 struct tm tm_datetime;
238 localtime_r(&l,&tm_datetime);
239 return cmyth_timestamp_from_tm(&tm_datetime);
244 * cmyth_timestamp_to_longlong( cmyth_timestamp_t ts)
250 * Create a time_t value from the timestamp structure 'ts' and
256 * Success: time_t value > 0 (seconds from January 1, 1970)
258 * Failure: (time_t) -1
261 cmyth_timestamp_to_unixtime(cmyth_timestamp_t ts)
264 tm.tm_sec = ts->timestamp_second;
265 tm.tm_min = ts->timestamp_minute;
266 tm.tm_hour = ts->timestamp_hour;
267 tm.tm_mday = ts->timestamp_day;
268 tm.tm_mon = ts->timestamp_month-1;
269 tm.tm_year = ts->timestamp_year-1900;
270 tm.tm_isdst = ts->timestamp_isdst;
275 * cmyth_timestamp_to_string(char *str, cmyth_timestamp_t ts)
281 * Create a string from the timestamp structure 'ts' and put it in the
282 * user supplied buffer 'str'. The size of 'str' must be
283 * CMYTH_TIMESTAMP_LEN + 1 or this will overwrite beyond 'str'.
293 cmyth_timestamp_to_string(char *str, cmyth_timestamp_t ts)
296 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL output string provided\n",
301 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp provided\n",
306 "%4.4ld-%2.2ld-%2.2ldT%2.2ld:%2.2ld:%2.2ld",
311 ts->timestamp_minute,
312 ts->timestamp_second);
317 * cmyth_timestamp_to_isostring(char *str, cmyth_timestamp_t ts)
323 * Create a string from the timestamp structure 'ts' and put it in the
324 * user supplied buffer 'str'. The size of 'str' must be
325 * CMYTH_TIMESTAMP_LEN + 1 or this will overwrite beyond 'str'.
335 cmyth_timestamp_to_isostring(char *str, cmyth_timestamp_t ts)
338 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL output string provided\n",
343 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp provided\n",
348 "%4.4ld-%2.2ld-%2.2ld",
356 cmyth_timestamp_to_display_string(char *str, cmyth_timestamp_t ts,
360 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL output string provided\n",
365 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp provided\n",
371 unsigned long hour = ts->timestamp_hour;
382 "%4.4ld-%2.2ld-%2.2ldT%2.2ld:%2.2ld:%2.2ld %s",
387 ts->timestamp_minute,
388 ts->timestamp_second,
394 "%4.4ld-%2.2ld-%2.2ldT%2.2ld:%2.2ld:%2.2ld",
399 ts->timestamp_minute,
400 ts->timestamp_second);
406 * cmyth_datetime_to_string(char *str, cmyth_timestamp_t ts)
412 * Create a string from the timestamp structure 'ts' and put it in the
413 * user supplied buffer 'str'. The size of 'str' must be
414 * CMYTH_DATETIME_LEN + 1 or this will overwrite beyond 'str'.
424 cmyth_datetime_to_string(char *str, cmyth_timestamp_t ts)
426 struct tm tm_datetime;
430 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL output string provided\n",
435 cmyth_dbg(CMYTH_DBG_ERROR, "%s: NULL timestamp provided\n",
440 memset(&tm_datetime, 0, sizeof(tm_datetime));
441 tm_datetime.tm_year = ts->timestamp_year - 1900;
442 tm_datetime.tm_mon = ts->timestamp_month - 1;
443 tm_datetime.tm_mday = ts->timestamp_day;
444 tm_datetime.tm_hour = ts->timestamp_hour;
445 tm_datetime.tm_min = ts->timestamp_minute;
446 tm_datetime.tm_sec = ts->timestamp_second;
447 tm_datetime.tm_isdst = ts->timestamp_isdst;
448 t_datetime = mktime(&tm_datetime);
450 "%4.4ld-%2.2ld-%2.2ldT%2.2ld:%2.2ld:%2.2ld",
455 ts->timestamp_minute,
456 ts->timestamp_second);
457 cmyth_dbg(CMYTH_DBG_ERROR, "original timestamp string: %s \n",str);
458 sprintf(str,"%lu",(unsigned long) t_datetime);
459 cmyth_dbg(CMYTH_DBG_ERROR, "time in seconds: %s \n",str);
467 * cmyth_timestamp_compare(cmyth_timestamp_t ts1, cmyth_timestamp_t ts2)
473 * Compare ts1 to ts2 and indicate whether ts1 is less than, equal to
474 * or greater than ts1.
479 * -1: ts1 is less than (erlier than) ts2
480 * 0: ts1 is the same as ts2
481 * 1: ts1 is greater than (later than) ts2
484 cmyth_timestamp_compare(cmyth_timestamp_t ts1, cmyth_timestamp_t ts2)
487 * If either timestamp is NULL it is 'less than' the non-NULL one
488 * (this is a stretch, but it shouldn't happen). If they are both
489 * NULL, they are equal.
500 if (ts1->timestamp_year != ts2->timestamp_year) {
501 return (ts1->timestamp_year > ts2->timestamp_year) ? 1 : -1;
503 if (ts1->timestamp_month != ts2->timestamp_month) {
504 return (ts1->timestamp_month > ts2->timestamp_month) ? 1 : -1;
506 if (ts1->timestamp_day != ts2->timestamp_day) {
507 return (ts1->timestamp_day > ts2->timestamp_day) ? 1 : -1;
509 if (ts1->timestamp_hour != ts2->timestamp_hour) {
510 return (ts1->timestamp_hour > ts2->timestamp_hour) ? 1 : -1;
512 if (ts1->timestamp_minute != ts2->timestamp_minute) {
513 return (ts1->timestamp_minute > ts2->timestamp_minute)
517 if (ts1->timestamp_second != ts2->timestamp_second) {
518 return (ts1->timestamp_second > ts2->timestamp_second)
526 cmyth_timestamp_diff(cmyth_timestamp_t ts1, cmyth_timestamp_t ts2)
528 struct tm tm_datetime;
531 memset(&tm_datetime, 0, sizeof(tm_datetime));
532 tm_datetime.tm_year = ts1->timestamp_year - 1900;
533 tm_datetime.tm_mon = ts1->timestamp_month - 1;
534 tm_datetime.tm_mday = ts1->timestamp_day;
535 tm_datetime.tm_hour = ts1->timestamp_hour;
536 tm_datetime.tm_min = ts1->timestamp_minute;
537 tm_datetime.tm_sec = ts1->timestamp_second;
538 tm_datetime.tm_isdst = ts1->timestamp_isdst;
539 start = mktime(&tm_datetime);
541 memset(&tm_datetime, 0, sizeof(tm_datetime));
542 tm_datetime.tm_year = ts2->timestamp_year - 1900;
543 tm_datetime.tm_mon = ts2->timestamp_month - 1;
544 tm_datetime.tm_mday = ts2->timestamp_day;
545 tm_datetime.tm_hour = ts2->timestamp_hour;
546 tm_datetime.tm_min = ts2->timestamp_minute;
547 tm_datetime.tm_sec = ts2->timestamp_second;
548 tm_datetime.tm_isdst = ts2->timestamp_isdst;
549 end = mktime(&tm_datetime);
551 return (int)(end - start);