1 #include "../include/datetime.h"
\r
4 #include "../include/stringfunctions.h"
\r
10 DateTime::DateTime()
\r
15 DateTime::DateTime(const time_t &timet)
\r
20 DateTime::DateTime(const struct tm *stm)
\r
25 void DateTime::Add(const int seconds, const int minutes, const int hours, const int days, const int months, const int years)
\r
27 m_tm.tm_sec+=seconds;
\r
28 m_tm.tm_min+=minutes;
\r
29 m_tm.tm_hour+=hours;
\r
31 m_tm.tm_mon+=months;
\r
32 m_tm.tm_year+=years;
\r
37 std::string DateTime::Format(const std::string &formatstring) const
\r
39 std::vector<char> str(256,0);
\r
41 size_t len=strftime(&str[0],str.size()-1,formatstring.c_str(),&m_tm);
\r
43 return std::string(str.begin(),str.begin()+len);
\r
46 void DateTime::Normalize()
\r
48 // check for tm_isdst in local time and take appropriate action when normalizing
\r
49 // thanks to http://www.erack.de/download/timetest.c for example
\r
53 temptimet=time(NULL);
\r
54 temptm=*localtime(&temptimet);
\r
55 isdst=temptm.tm_isdst;
\r
57 temptm.tm_year=m_tm.tm_year;
\r
58 temptm.tm_mon=m_tm.tm_mon;
\r
59 temptm.tm_mday=m_tm.tm_mday;
\r
60 temptm.tm_hour=m_tm.tm_hour;
\r
61 temptm.tm_min=m_tm.tm_min;
\r
62 temptm.tm_sec=m_tm.tm_sec;
\r
63 temptm.tm_isdst=isdst;
\r
64 temptimet=mktime(&temptm);
\r
66 if(temptm.tm_isdst!=isdst)
\r
68 // keep tm_isdst to whatever mktime returned and try again
\r
69 temptm.tm_year=m_tm.tm_year;
\r
70 temptm.tm_mon=m_tm.tm_mon;
\r
71 temptm.tm_mday=m_tm.tm_mday;
\r
72 temptm.tm_hour=m_tm.tm_hour;
\r
73 temptm.tm_min=m_tm.tm_min;
\r
74 temptm.tm_sec=m_tm.tm_sec;
\r
75 temptimet=mktime(&temptm);
\r
77 else if(isdst && temptimet==-1)
\r
79 // isdst set, but TZ has no offset (e.g. GMT), try with isdst=0
\r
80 temptm.tm_year=m_tm.tm_year;
\r
81 temptm.tm_mon=m_tm.tm_mon;
\r
82 temptm.tm_mday=m_tm.tm_mday;
\r
83 temptm.tm_hour=m_tm.tm_hour;
\r
84 temptm.tm_min=m_tm.tm_min;
\r
85 temptm.tm_sec=m_tm.tm_sec;
\r
87 temptimet=mktime(&temptm);
\r
93 // date is erroneous - set to default date
\r
94 if(m_timet==-1 && (m_tm.tm_mon<0 || m_tm.tm_mon>11 || m_tm.tm_mday <1 || m_tm.tm_mday>31 || m_tm.tm_hour<0 || m_tm.tm_hour>23 || m_tm.tm_min<0 || m_tm.tm_min>59 || m_tm.tm_sec<0 || m_tm.tm_sec>59))
\r
101 DateTime DateTime::operator+(const double &rhs)
\r
103 DateTime temp=*this;
\r
109 int hours=(int)val;
\r
112 int minutes=(int)val;
\r
115 int seconds=(int)val;
\r
117 temp.Add(seconds,minutes,hours,days);
\r
121 DateTime DateTime::operator+(const DateTime &rhs)
\r
123 DateTime temp=*this;
\r
125 temp.Add(rhs.m_tm.tm_sec,rhs.m_tm.tm_min,rhs.m_tm.tm_hour,rhs.m_tm.tm_mday,rhs.m_tm.tm_mon+1,rhs.m_tm.tm_year+1900);
\r
129 DateTime &DateTime::operator+=(const double &rhs)
\r
136 DateTime &DateTime::operator+=(const DateTime &rhs)
\r
143 DateTime DateTime::operator-(const double &rhs)
\r
145 DateTime temp=*this;
\r
151 int hours=(int)val;
\r
154 int minutes=(int)val;
\r
157 int seconds=(int)val;
\r
159 temp.Add(-seconds,-minutes,-hours,-days);
\r
163 DateTime DateTime::operator-(const DateTime &rhs)
\r
165 DateTime temp=*this;
\r
167 temp.Add(-rhs.m_tm.tm_sec,-rhs.m_tm.tm_min,-rhs.m_tm.tm_hour,-rhs.m_tm.tm_mday,-(rhs.m_tm.tm_mon+1),-(rhs.m_tm.tm_year+1900));
\r
171 DateTime &DateTime::operator-=(const double &rhs)
\r
178 DateTime &DateTime::operator-=(const DateTime &rhs)
\r
185 const bool DateTime::operator==(const struct tm &rhs) const
\r
187 return (m_tm.tm_year==rhs.tm_year && m_tm.tm_mon==rhs.tm_mon && m_tm.tm_mday==rhs.tm_mday && m_tm.tm_hour==rhs.tm_hour && m_tm.tm_min==rhs.tm_min && m_tm.tm_sec==rhs.tm_sec) ? true : false;
\r
190 const bool DateTime::operator<(const struct tm &rhs) const
\r
192 return (m_tm.tm_year<rhs.tm_year || (m_tm.tm_year==rhs.tm_year && m_tm.tm_mon<rhs.tm_mon) || (m_tm.tm_year==rhs.tm_year && m_tm.tm_mon==rhs.tm_mon && m_tm.tm_mday<rhs.tm_mday) || (m_tm.tm_year==rhs.tm_year && m_tm.tm_mon==rhs.tm_mon && m_tm.tm_mday==rhs.tm_mday && m_tm.tm_hour<rhs.tm_hour) || (m_tm.tm_year==rhs.tm_year && m_tm.tm_mon==rhs.tm_mon && m_tm.tm_mday==rhs.tm_mday && m_tm.tm_hour==rhs.tm_hour && m_tm.tm_min<rhs.tm_min) || (m_tm.tm_year==rhs.tm_year && m_tm.tm_mon==rhs.tm_mon && m_tm.tm_mday==rhs.tm_mday && m_tm.tm_hour==rhs.tm_hour && m_tm.tm_min==rhs.tm_min && m_tm.tm_sec==rhs.tm_sec));
\r
195 void DateTime::Set(const int year, const int month, const int day, const int hour, const int minute, const int second)
\r
197 m_tm.tm_year=year-1900;
\r
198 m_tm.tm_mon=month-1;
\r
201 m_tm.tm_min=minute;
\r
202 m_tm.tm_sec=second;
\r
207 void DateTime::SetT(const time_t &timet)
\r
211 m_tm=*gmtime(&m_timet);
\r
215 void DateTime::Set(const struct tm *stm)
\r
218 m_timet=mktime(&m_tm);
\r
222 void DateTime::Set(const std::string &datestring)
\r
224 int year,month,day,hour,minute,second;
\r
225 std::vector<std::string> tokens;
\r
226 std::vector<std::string>::size_type vecpos;
\r
229 year=month=day=hour=minute=second=-1;
\r
231 // reset to 1900-01-01 00:00:00
\r
234 StringFunctions::SplitMultiple(datestring,"-/\\., :",tokens);
\r
236 // loop through 1st time to try to find 4 digit year and month (if it is a text month)
\r
238 for(std::vector<std::string>::iterator i=tokens.begin(); i!=tokens.end(); i++,vecpos++)
\r
240 StringFunctions::UpperCase((*i),(*i));
\r
242 if((*i).find("JAN")==0)
\r
247 if((*i).find("FEB")==0)
\r
252 if((*i).find("MAR")==0)
\r
257 if((*i).find("APR")==0)
\r
262 if((*i).find("MAY")==0)
\r
267 if((*i).find("JUN")==0)
\r
272 if((*i).find("JUL")==0)
\r
277 if((*i).find("AUG")==0)
\r
282 if((*i).find("SEP")==0)
\r
287 if((*i).find("OCT")==0)
\r
292 if((*i).find("NOV")==0)
\r
297 if((*i).find("DEC")==0)
\r
303 // if we just got month - day is probaby in the next position
\r
304 if(month==vecpos && vecpos+1<tokens.size() && tokens[vecpos+1].size()>0)
\r
307 StringFunctions::Convert(tokens[vecpos+1],tempint);
\r
308 if(tempint>0 && tempint<32)
\r
315 // if this is not month or day, and the size is 4 then it is probably the year
\r
316 if(month!=vecpos && day!=vecpos && (*i).size()==4)
\r
319 StringFunctions::Convert((*i),tempint);
\r
326 // month is probably right after year
\r
327 if(year!=-1 && month==-1 && year+1<tokens.size())
\r
330 StringFunctions::Convert(tokens[year+1],tempint);
\r
331 if(tempint>=1 && tempint<=12)
\r
338 // otherwise it is probably 2 steps back (m/d/y)
\r
339 if(year!=-1 && month==-1 && year-2>=0)
\r
342 StringFunctions::Convert(tokens[year-2],tempint);
\r
343 if(tempint>=1 && tempint<=12)
\r
350 // day is probably right after month
\r
351 if(month!=-1 && month+1<tokens.size())
\r
354 StringFunctions::Convert(tokens[month+1],tempint);
\r
355 if(tempint>=1 && tempint<32)
\r
362 // loop through another time to find hour
\r
364 for(std::vector<std::string>::iterator i=tokens.begin(); i!=tokens.end(); i++,vecpos++)
\r
366 if(vecpos!=year && vecpos!=month && vecpos!=day && hour==-1)
\r
369 StringFunctions::Convert((*i),tempint);
\r
370 if(tempint>=0 && tempint<24)
\r
378 // minute right after hour
\r
379 if(hour!=-1 && hour+1<tokens.size())
\r
382 StringFunctions::Convert(tokens[hour+1],tempint);
\r
383 if(tempint>=0 && tempint<60)
\r
385 SetMinute(tempint);
\r
390 //second right after minute
\r
391 if(minute!=-1 && minute+1<tokens.size())
\r
394 StringFunctions::Convert(tokens[minute+1],tempint);
\r
395 if(tempint>=0 && tempint<60)
\r
397 SetSecond(tempint);
\r
404 void DateTime::SetToGMTime()
\r
406 m_timet=time(NULL);
\r
408 m_tm=*gmtime(&m_timet);
\r
412 void DateTime::SetToLocalTime()
\r
414 m_timet=time(NULL);
\r
415 m_tm=*localtime(&m_timet);
\r
419 const time_t DateTime::TimeGM(struct tm *gmtimein)
\r
421 //This looks good but I don't think will work when TZ isn't set (Windows)
\r
422 //http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/timegm.3.html
\r
425 //http://lists2.ais.fraunhofer.de/pipermail/emx/1999-September/000874.html
\r
430 ttm = *gmtimein; /* make a local copy to fiddle with */
\r
431 ttm.tm_isdst = 0; /* treat it as standard time */
\r
433 t2 = t = mktime(&ttm); /* calculate the time as a local time */
\r
435 ttm = *gmtime(&t2); /* now calculate the difference between */
\r
436 ttm.tm_isdst = 0; /* gm and local time */
\r
439 t += t - t2; /* and adjust our answer by that difference */
\r