jabberd2  2.2.16
util/datetime.c
Go to the documentation of this file.
00001 /*
00002  * jabberd - Jabber Open Source Server
00003  * Copyright (c) 2002-2003 Jeremie Miller, Thomas Muldowney,
00004  *                         Ryan Eatmon, Robert Norris
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
00019  */
00020 
00021 #include "util.h"
00022 
00023 /* ISO 8601 / JEP-0082 date/time manipulation */
00024 
00025 /* formats */
00026 #define DT_DATETIME_P       "%04d-%02d-%02dT%02d:%02d:%lf+%02d:%02d"
00027 #define DT_DATETIME_M       "%04d-%02d-%02dT%02d:%02d:%lf-%02d:%02d"
00028 #define DT_DATETIME_Z       "%04d-%02d-%02dT%02d:%02d:%lfZ"
00029 #define DT_TIME_P           "%02d:%02d:%lf+%02d:%02d"
00030 #define DT_TIME_M           "%02d:%02d:%lf-%02d:%02d"
00031 #define DT_TIME_Z           "%02d:%02d:%lfZ"
00032 #define DT_LEGACY           "%04d%02d%02dT%02d:%02d:%lf"
00033 
00034 time_t datetime_in(char *date) {
00035     struct tm gmt, off;
00036     double sec;
00037     off_t fix = 0;
00038     struct timeval tv;
00039     struct timezone tz;
00040 
00041     assert((int) (date != NULL));
00042 
00043     /* !!! sucks having to call this each time */
00044     tzset();
00045 
00046     memset(&gmt, 0, sizeof(struct tm));
00047     memset(&off, 0, sizeof(struct tm));
00048 
00049     if(sscanf(date, DT_DATETIME_P,
00050                    &gmt.tm_year, &gmt.tm_mon, &gmt.tm_mday,
00051                    &gmt.tm_hour, &gmt.tm_min, &sec,
00052                    &off.tm_hour, &off.tm_min) == 8) {
00053         gmt.tm_sec = (int) sec;
00054         gmt.tm_year -= 1900;
00055         gmt.tm_mon--;
00056         fix = off.tm_hour * 3600 + off.tm_min * 60;
00057     }
00058 
00059     else if(sscanf(date, DT_DATETIME_M,
00060                    &gmt.tm_year, &gmt.tm_mon, &gmt.tm_mday,
00061                    &gmt.tm_hour, &gmt.tm_min, &sec,
00062                    &off.tm_hour, &off.tm_min) == 8) {
00063         gmt.tm_sec = (int) sec;
00064         gmt.tm_year -= 1900;
00065         gmt.tm_mon--;
00066         fix = - off.tm_hour * 3600 - off.tm_min * 60;
00067     }
00068 
00069     else if(sscanf(date, DT_DATETIME_Z,
00070                    &gmt.tm_year, &gmt.tm_mon, &gmt.tm_mday,
00071                    &gmt.tm_hour, &gmt.tm_min, &sec) == 6) {
00072         gmt.tm_sec = (int) sec;
00073         gmt.tm_year -= 1900;
00074         gmt.tm_mon--;
00075         fix = 0;
00076     }
00077 
00078     else if(sscanf(date, DT_TIME_P,
00079                    &gmt.tm_hour, &gmt.tm_min, &sec,
00080                    &off.tm_hour, &off.tm_min) == 5) {
00081         gmt.tm_sec = (int) sec;
00082         fix = off.tm_hour * 3600 + off.tm_min * 60;
00083     }
00084 
00085     else if(sscanf(date, DT_TIME_M,
00086                    &gmt.tm_hour, &gmt.tm_min, &sec,
00087                    &off.tm_hour, &off.tm_min) == 5) {
00088         gmt.tm_sec = (int) sec;
00089         fix = - off.tm_hour * 3600 - off.tm_min * 60;
00090     }
00091 
00092     else if(sscanf(date, DT_TIME_Z,
00093                    &gmt.tm_hour, &gmt.tm_min, &sec) == 3) {
00094         gmt.tm_sec = (int) sec;
00095         fix = - off.tm_hour * 3600 - off.tm_min * 60;
00096     }
00097 
00098     else if(sscanf(date, DT_LEGACY,
00099                    &gmt.tm_year, &gmt.tm_mon, &gmt.tm_mday,
00100                    &gmt.tm_hour, &gmt.tm_min, &sec) == 6) {
00101         gmt.tm_sec = (int) sec;
00102         gmt.tm_year -= 1900;
00103         gmt.tm_mon--;
00104         fix = 0;
00105     }
00106 
00107     gmt.tm_isdst = -1;
00108 
00109     gettimeofday(&tv, &tz);
00110 
00111     return mktime(&gmt) + fix - (tz.tz_minuteswest * 60);
00112 }
00113 
00114 void datetime_out(time_t t, datetime_t type, char *date, int datelen) {
00115     struct tm *gmt;
00116 
00117     assert((int) type);
00118     assert((int) (date != NULL));
00119     assert((int) datelen);
00120 
00121     gmt = gmtime(&t);
00122 
00123     switch(type) {
00124         case dt_DATE:
00125             snprintf(date, datelen, "%04d-%02d-%02d", gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday);
00126             break;
00127 
00128         case dt_TIME:
00129             snprintf(date, datelen, "%02d:%02d:%02dZ", gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
00130             break;
00131 
00132         case dt_DATETIME:
00133             snprintf(date, datelen, "%04d-%02d-%02dT%02d:%02d:%02dZ", gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday, gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
00134             break;
00135 
00136         case dt_LEGACY:
00137             snprintf(date, datelen, "%04d%02d%02dT%02d:%02d:%02d", gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday, gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
00138             break;
00139     }
00140 }