/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Calibration/facilities/facilities-00-00-04/src/Timestamp.cxx

Go to the documentation of this file.
00001 // $Header: /bes/bes/BossCvs/Calibration/facilities/src/Timestamp.cxx,v 1.1.1.1 2005/10/17 06:11:40 maqm Exp $
00002 
00003 #include <ctime>
00004 #include <cstdlib>
00005 #include <cstdio>
00006 #include <cmath>
00007 #include "facilities/Timestamp.h"
00008 
00009 namespace facilities {
00010   const double Timestamp::julian1970 = 2440587.5;
00011   const int    Timestamp::secPerDay =  (24*60*60);
00012   const double Timestamp::inverseNano = 1000 * 1000 * 1000;
00013   const int    Timestamp::inverseNanoInt = 1000 * 1000 * 1000;
00014   const long int Timestamp::maxInt = 0x7fffffff;
00015   
00016   Timestamp::TZOffset Timestamp::s_tz;
00017 
00018   // return current time (resolution of 1 second)
00019   Timestamp::Timestamp() : m_nano(0) {
00020     m_time = time(0);
00021   }
00022 
00023   // time specified as seconds since 1970 in the timezone corresponding
00024   // to tzOffset (measured in seconds) west of GMT.  So, for example, 
00025   // a local time PST should have tzOffset = 28800; PDT would be 25200;
00026   // EST is 18000 and so forth. This offset can be read from the
00027   // system variable __timezone
00028   Timestamp::Timestamp(long int seconds, int nano, int tzOffset)
00029     : m_time((time_t) seconds), m_nano(nano)
00030   {
00031     if  ((nano >= inverseNanoInt)  || (nano < 0) || (seconds < 0))
00032       throw BadTimeInput("facilities::Timestamp bad nano argument");
00033     seconds += tzOffset;
00034   }
00035 
00036   // time specified as Julian date
00037   Timestamp::Timestamp(double julian) {
00038     double secs;
00039     secs = (julian - julian1970) * secPerDay;
00040 
00041     if ((fabs(secs) > maxInt) || (secs < 0) )
00042       throw BadTimeInput("Julian time not in range [1970, 2037]");
00043 
00044     m_time = (long int) secs;
00045 
00046     // In case time is negative, truncation will go the "wrong way".
00047     // Want m_time always <= secs
00048     if (m_time > secs) m_time--;
00049     m_nano = (int) ((secs - m_time)/inverseNano);
00050   } 
00051 
00052   // Time specified as string
00053   Timestamp::Timestamp(const std::string& str, int tzOffset) : m_nano(0) {
00054     m_time = toBinary(str);
00055     m_time += tzOffset;
00056   }
00057 
00058   // Time specified with independent fields
00059   Timestamp::Timestamp(int year, int month, 
00060                        int day, int hour, 
00061                        int minute, int second,
00062                        int nano) :  m_nano(nano) {
00063     struct tm fields;
00064 
00065     // check input   
00066     // for now don't bother checking whether, e.g., someone
00067     // specified April 31
00068     if ((month < 1 ) || (month > 12) || (day < 1) || (day > 31) ||
00069         (hour < 0) || (hour > 23) || 
00070         (minute < 0) || (minute > 59) || 
00071         (second < 0 ) || (second >= 60) ||
00072         (year < 1970) || (year > 2037) || 
00073         (nano < 0 ) || (nano >= inverseNanoInt) ) 
00074       throw BadTimeInput("facilities::Timestamp Bad subfield");
00075 
00076     fields.tm_year = year - 1900;
00077     fields.tm_mon = month - 1;
00078     fields.tm_mday = day;
00079     fields.tm_hour = hour;
00080     fields.tm_min = minute;
00081     fields.tm_sec = (long int) second;
00082     fields.tm_wday = -1;
00083     fields.tm_yday = -1;
00084     
00085     // let system figure out whether daylight savings time is in effect
00086     fields.tm_isdst = 0;
00087 
00088     //    m_time = timegm(&fields);
00089     m_time = mktime(&fields) - Timestamp::s_tz.m_tzseconds;
00090   }
00091 
00092   std::string Timestamp::getString() const {
00093     std::string str;
00094 
00095     toString(m_time, str);
00096     return str;
00097   }
00098 
00099   double  Timestamp::getJulian() const {
00100     double julian = (m_time +  m_nano/inverseNano)/secPerDay;
00101     julian += julian1970;
00102     return julian;
00103   }
00104 
00105 
00106   time_t Timestamp::toBinary(const std::string& strTime) {
00107     // Break out fields
00108     struct tm fields;
00109 
00110     unsigned int pos;
00111     unsigned int oldPos = 0;
00112 
00113     // Three delimiter characters may occur in ascii time representation.
00114     // First is hyphen.
00115     char  delim = '-';
00116 
00117     pos = strTime.find(delim, oldPos);
00118 
00119     // Must have two occurrences of hyphen delimiter
00120     if (pos >= strTime.size()) return 0;
00121 
00122     fields.tm_year = atoi((strTime.substr(oldPos, pos)).c_str()) - 1900;
00123     if ((fields.tm_year < 70) || (fields.tm_year > 137)) 
00124       throw BadTimeInput("facilities::Timestamp  bad year");
00125     oldPos = pos + 1;
00126     pos = strTime.find(delim, oldPos);
00127 
00128     // Should have at least two occurrences of delim
00129     if (pos >= strTime.size()) 
00130       throw BadTimeInput("Bad string format for facilities::Timestamp");
00131 
00132     fields.tm_mon = atoi((strTime.substr(oldPos, pos)).c_str()) - 1;
00133     if ((fields.tm_mon < 0) || (fields.tm_mon > 11)) 
00134       throw BadTimeInput("facilities::Timestamp bad month");
00135 
00136     // day
00137     oldPos = pos + 1;
00138 
00139     // A space separates time from date (if time is present at all)
00140     delim = ' ';
00141     pos = strTime.find(delim, oldPos);
00142 
00143     fields.tm_mday = atoi((strTime.substr(oldPos, pos)).c_str());
00144 
00145     if ((fields.tm_mday < 1) || (fields.tm_mday > 31))
00146     throw BadTimeInput("facilities::Timestamp bad day of month");
00147 
00148     // Remaining fields in string representation default to 0.
00149     fields.tm_hour = fields.tm_min = fields.tm_sec = 0;
00150 
00151     if (pos < strTime.size() ) {   // more fields to process
00152       delim = ':';
00153       oldPos = pos + 1;
00154 
00155       pos = strTime.find(delim, oldPos);
00156 
00157       fields.tm_hour = atoi((strTime.substr(oldPos, pos)).c_str());
00158       if ((fields.tm_hour > 23) || (fields.tm_hour < 0)) 
00159       throw BadTimeInput("facilities::Timestamp bad hour");
00160 
00161       
00162       if (pos < strTime.size() ) {
00163         oldPos = pos + 1;
00164         pos = strTime.find(delim, oldPos);
00165         fields.tm_min = atoi((strTime.substr(oldPos, pos)).c_str());
00166         if ((fields.tm_min > 59) || (fields.tm_hour < 0))
00167           throw BadTimeInput("facilities::Timestamp bad minutes");
00168 
00169         if (pos < strTime.size() ) {
00170           oldPos = pos + 1;
00171           pos = strTime.find(delim, oldPos);
00172           fields.tm_sec = atoi((strTime.substr(oldPos, pos)).c_str());
00173           if ((fields.tm_sec > 59) || (fields.tm_hour < 0)) 
00174             throw BadTimeInput("facilities::Timestamp bad seconds");
00175         }
00176       }
00177     }
00178 
00179     fields.tm_wday = -1;
00180     fields.tm_yday = -1;
00181     fields.tm_isdst = 0;
00182     return mktime(&fields)  - Timestamp::s_tz.m_tzseconds;
00183   }
00184   
00185   void Timestamp::toString(time_t bin, std::string& strTime) {
00186     struct tm * fields = gmtime(&bin);
00187 
00188     strTime.resize(0);
00189     
00190     char buf[20];
00191     char* bufPtr = &buf[0];
00192     sprintf(buf, "%i", fields->tm_year + 1900);
00193     strTime += bufPtr; strTime +=  "-";
00194     sprintf(buf, "%02i", fields->tm_mon +1);
00195     strTime += bufPtr; strTime +=  "-";
00196     sprintf(buf, "%02i", fields->tm_mday);
00197     strTime += bufPtr; strTime +=  " ";
00198     sprintf(buf, "%02i", fields->tm_hour);
00199     strTime += bufPtr; strTime +=  ":";
00200     sprintf(buf, "%02i", fields->tm_min);
00201     strTime += bufPtr; strTime +=  ":";
00202     sprintf(buf, "%02i", fields->tm_sec);
00203     strTime += bufPtr;
00204   }
00205 
00206 
00207   Timestamp::TZOffset::TZOffset() {
00208     struct tm fields;
00209 
00210     // Set it up for Jan 1, 1970 at 12:00
00211     fields.tm_year = 70;
00212     fields.tm_mon = 0;
00213     fields.tm_mday = 1;
00214     fields.tm_hour = 12;
00215     fields.tm_min = 0;
00216     fields.tm_sec = 0;
00217     fields.tm_isdst = 0;
00218 
00219     m_tzseconds = mktime(&fields) - 12*60*60;
00220     m_isDst = fields.tm_isdst;
00221   }
00222 }
00223 
00224 
00225 
00226 
00227 
00228 

Generated on Tue Nov 29 22:57:56 2016 for BOSS_7.0.2 by  doxygen 1.4.7