Drizzled Public API Documentation

CSTime.cc
00001 /* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
00002  *
00003  * PrimeBase Media Stream for MySQL
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00018  *
00019  * Original author: Paul McCullagh (H&G2JCtL)
00020  * Continued development: Barry Leslie
00021  *
00022  * 2007-05-20
00023  *
00024  *
00025  */
00026 
00027 #include "CSConfig.h"
00028 
00029 #include <string.h>
00030 
00031 #ifdef OS_WINDOWS
00032 #include <Windows.h>
00033 extern int gettimeofday(struct timeval *tv, struct timezone *tz);
00034 #else
00035 #include <sys/time.h>
00036 #endif
00037 
00038 #include "CSTime.h"
00039 #include "CSGlobal.h"
00040 #include "CSStrUtil.h"
00041 
00042 /*
00043  * timegm() is a none portable function so....
00044  * This is an implimentation of timegm() based on one found
00045  * here: http://www.opensync.org/changeset/1769
00046  *
00047  * Note to self: There is a better way to do this.
00048  * Since this is just used internally and tm_isdst is always 0
00049  * we only need to calculate the timezone offset to GM time once.
00050  */
00051 static time_t my_timegm(struct tm *my_time)
00052 {
00053   time_t local_secs, gm_secs;
00054   struct tm gm__rec, *gm_time;
00055 
00056   // Interpret 't' as the local time and convert it to seconds since the Epoch
00057   local_secs = mktime(my_time);
00058   if (local_secs == -1) {
00059     my_time->tm_hour--;
00060     local_secs = mktime (my_time);
00061     if (local_secs == -1)
00062       return -1; 
00063     local_secs += 3600;
00064   }
00065   
00066   // Get the gmtime based on the local seconds since the Epoch
00067   gm_time = gmtime_r(&local_secs, &gm__rec);
00068   gm_time->tm_isdst = 0;
00069   
00070   // Interpret gmtime as the local time and convert it to seconds since the Epoch
00071   gm_secs = mktime (gm_time);
00072   if (gm_secs == -1) {
00073     gm_time->tm_hour--;
00074     gm_secs = mktime (gm_time);
00075     if (gm_secs == -1)
00076       return -1; 
00077     gm_secs += 3600;
00078   }
00079   
00080   // Return the local time adjusted by the difference from GM time.
00081   return (local_secs - (gm_secs - local_secs));
00082 }
00083 
00084 CSTime::CSTime(s_int year, s_int mon, s_int day, s_int hour, s_int min, s_int sec, s_int nsec)
00085 {
00086   setLocal(year, mon, day, hour, min, sec, nsec);
00087 }
00088 
00089 bool CSTime::isNull()
00090 {
00091   return iIsNull;
00092 }
00093 
00094 void CSTime::setNull()
00095 {
00096   iIsNull = true;
00097   iSeconds = 0;
00098   iNanoSeconds = 0;
00099 }
00100 
00101 void CSTime::setLocal(s_int year, s_int mon, s_int day, s_int hour, s_int min, s_int sec, s_int nsec)
00102 {
00103   struct tm ltime;
00104   time_t    secs;
00105   
00106   memset(&ltime, 0, sizeof(ltime));
00107 
00108   ltime.tm_sec = sec;
00109   ltime.tm_min = min;
00110   ltime.tm_hour = hour;
00111   ltime.tm_mday = day;
00112   ltime.tm_mon = mon - 1;
00113   ltime.tm_year = year - 1900;
00114   secs = mktime(&ltime);
00115   setUTC1970(secs, nsec);
00116 }
00117 
00118 void CSTime::getLocal(s_int& year, s_int& mon, s_int& day, s_int& hour, s_int& min, s_int& sec, s_int& nsec)
00119 {
00120   struct tm ltime;
00121   time_t    secs;
00122 
00123   memset(&ltime, 0, sizeof(ltime));
00124   
00125   getUTC1970(secs, nsec);
00126   localtime_r(&secs, &ltime);
00127   sec = ltime.tm_sec;
00128   min = ltime.tm_min;
00129   hour = ltime.tm_hour;
00130   day = ltime.tm_mday;
00131   mon = ltime.tm_mon + 1;
00132   year = ltime.tm_year + 1900;
00133 }
00134 
00135 void CSTime::setUTC(s_int year, s_int mon, s_int day, s_int hour, s_int min, s_int sec, s_int nsec)
00136 {
00137   iNanoSeconds = nsec;
00138   iSeconds = sec;
00139   iMinutes = min;
00140   iHours = hour;
00141   iDay = day;
00142   iMonth = mon;
00143   iYear = year;
00144   iIsNull = false;
00145 }
00146 
00147 void CSTime::getUTC(s_int& year, s_int& mon, s_int& day, s_int& hour, s_int& min, s_int& sec, s_int& nsec)
00148 {
00149   nsec = iNanoSeconds;
00150   sec = iSeconds;
00151   min = iMinutes;
00152   hour = iHours;
00153   day = iDay;
00154   mon = iMonth;
00155   year = iYear;
00156 }
00157 
00158 char *CSTime::getCString(const char *format)
00159 {
00160   if (iIsNull)
00161     strcpy(iCString, "NULL");
00162   else {
00163     struct tm ltime;
00164     time_t    secs;
00165     s_int   nsec;
00166 
00167     memset(&ltime, 0, sizeof(ltime));
00168   
00169     getUTC1970(secs, nsec);
00170     localtime_r(&secs, &ltime);
00171     strftime(iCString, 100, format, &ltime);
00172   }
00173   return iCString;
00174 }
00175 
00176 char *CSTime::getCString()
00177 {
00178   return getCString("%Y-%m-%d %H:%M:%S");
00179 }
00180 
00181 void CSTime::setUTC1970(time_t sec, s_int nsec)
00182 {
00183   struct tm ltime;
00184 
00185   memset(&ltime, 0, sizeof(ltime));
00186 
00187   gmtime_r(&sec, &ltime);
00188   setUTC(ltime.tm_year + 1900, ltime.tm_mon + 1, ltime.tm_mday, ltime.tm_hour, ltime.tm_min, ltime.tm_sec, nsec);
00189 }
00190 
00191 bool CSTime::olderThen(time_t max_age)
00192 {
00193   time_t secs, now;
00194   s_int nsec;
00195   
00196   getUTC1970(secs, nsec);
00197   
00198   now = time(NULL);
00199   
00200   return ((now - secs) > max_age);
00201 }
00202 
00203 void CSTime::getUTC1970(time_t& sec, s_int& nsec)
00204 {
00205 #ifdef OS_WINDOWS
00206   uint64_t nsec100;
00207 
00208   /* Get the number of seconds since 1 Jan 1970 */
00209   nsec100 = getUTC1601();
00210   nsec100 = nsec100 - get1970as1601();
00211   sec = (time_t) (nsec100 / 10000000);
00212 #else
00213   struct tm ltime;
00214 
00215   memset(&ltime, 0, sizeof(ltime));
00216 
00217   ltime.tm_sec = iSeconds;
00218   ltime.tm_min = iMinutes;
00219   ltime.tm_hour = iHours;
00220   ltime.tm_mday = iDay;
00221   ltime.tm_mon = iMonth - 1;
00222   ltime.tm_year = iYear - 1900;
00223   sec = my_timegm(&ltime);
00224 #endif
00225   nsec = iNanoSeconds;
00226 }
00227 
00228 #ifdef OS_WINDOWS
00229 
00230 void CSTime::setUTC1601(uint64_t nsec100)
00231 {
00232   FILETIME    ftime;
00233   SYSTEMTIME    stime;
00234 
00235   /* The input is actually a FILETIME value: */
00236   memcpy(&ftime, &nsec100, sizeof(ftime));
00237 
00238   if (!FileTimeToSystemTime(&ftime, &stime))
00239     CSException::throwLastError(CS_CONTEXT);
00240   setUTC((s_int) stime.wYear, (s_int) stime.wMonth, (s_int) stime.wDay,
00241     (s_int) stime.wHour, (s_int) stime.wMinute, (s_int) stime.wSecond, (s_int) stime.wMilliseconds * 1000);
00242 }
00243 
00244 uint64_t CSTime::getUTC1601()
00245 {
00246   FILETIME  ftime;
00247   SYSTEMTIME  stime;
00248   uint64_t    nsec100;
00249 
00250   stime.wYear = iYear;
00251   stime.wMonth = iMonth;
00252   stime.wDay = iDay;
00253   stime.wHour = iHours;
00254   stime.wMinute = iMinutes;
00255   stime.wSecond = iSeconds;
00256   stime.wMilliseconds = iNanoSeconds / 1000;
00257   if (!SystemTimeToFileTime(&stime, &ftime))
00258     CSException::throwLastError(CS_CONTEXT);
00259   memcpy(&nsec100, &ftime, sizeof(nsec100));
00260   return nsec100;
00261 }
00262 
00263 uint64_t CSTime::get1970as1601()
00264 {
00265   FILETIME  ftime;
00266   SYSTEMTIME  stime;
00267   uint64_t    nsec100;
00268 
00269   stime.wYear = 1970;
00270   stime.wMonth = 1;
00271   stime.wDay = 1;
00272   stime.wHour = 0;
00273   stime.wMinute = 0;
00274   stime.wSecond = 0;
00275   stime.wMilliseconds = 0;
00276   if (!SystemTimeToFileTime(&stime, &ftime))
00277     CSException::throwLastError(CS_CONTEXT);
00278   memcpy(&nsec100, &ftime, sizeof(nsec100));
00279   return nsec100;
00280 }
00281 
00282 #endif
00283 
00284 uint64_t CSTime::getTimeCurrentTicks()
00285 {
00286   struct timeval  now;
00287 
00288   /* Get the current time in microseconds: */
00289   gettimeofday(&now, NULL);
00290   return (uint64_t) now.tv_sec * (uint64_t) 1000000 + (uint64_t) now.tv_usec;
00291 }
00292 
00293 
00294