2 * Copyright (C) 2005-2008 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program 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
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "XBDateTime.h"
24 #include "guilib/LocalizeStrings.h"
26 #define SECONDS_PER_DAY 86400UL
27 #define SECONDS_PER_HOUR 3600UL
28 #define SECONDS_PER_MINUTE 60UL
29 #define SECONDS_TO_FILETIME 10000000UL
31 /////////////////////////////////////////////////
36 CDateTimeSpan::CDateTimeSpan()
38 m_timeSpan.dwHighDateTime=0;
39 m_timeSpan.dwLowDateTime=0;
42 CDateTimeSpan::CDateTimeSpan(const CDateTimeSpan& span)
44 m_timeSpan.dwHighDateTime=span.m_timeSpan.dwHighDateTime;
45 m_timeSpan.dwLowDateTime=span.m_timeSpan.dwLowDateTime;
48 CDateTimeSpan::CDateTimeSpan(int day, int hour, int minute, int second)
50 SetDateTimeSpan(day, hour, minute, second);
53 bool CDateTimeSpan::operator >(const CDateTimeSpan& right) const
55 return CompareFileTime(&m_timeSpan, &right.m_timeSpan)>0;
58 bool CDateTimeSpan::operator >=(const CDateTimeSpan& right) const
60 return operator >(right) || operator ==(right);
63 bool CDateTimeSpan::operator <(const CDateTimeSpan& right) const
65 return CompareFileTime(&m_timeSpan, &right.m_timeSpan)<0;
68 bool CDateTimeSpan::operator <=(const CDateTimeSpan& right) const
70 return operator <(right) || operator ==(right);
73 bool CDateTimeSpan::operator ==(const CDateTimeSpan& right) const
75 return CompareFileTime(&m_timeSpan, &right.m_timeSpan)==0;
78 bool CDateTimeSpan::operator !=(const CDateTimeSpan& right) const
80 return !operator ==(right);
83 CDateTimeSpan CDateTimeSpan::operator +(const CDateTimeSpan& right) const
85 CDateTimeSpan left(*this);
87 ULARGE_INTEGER timeLeft;
88 left.ToULargeInt(timeLeft);
90 ULARGE_INTEGER timeRight;
91 right.ToULargeInt(timeRight);
93 timeLeft.QuadPart+=timeRight.QuadPart;
95 left.FromULargeInt(timeLeft);
100 CDateTimeSpan CDateTimeSpan::operator -(const CDateTimeSpan& right) const
102 CDateTimeSpan left(*this);
104 ULARGE_INTEGER timeLeft;
105 left.ToULargeInt(timeLeft);
107 ULARGE_INTEGER timeRight;
108 right.ToULargeInt(timeRight);
110 timeLeft.QuadPart-=timeRight.QuadPart;
112 left.FromULargeInt(timeLeft);
117 const CDateTimeSpan& CDateTimeSpan::operator +=(const CDateTimeSpan& right)
119 ULARGE_INTEGER timeThis;
120 ToULargeInt(timeThis);
122 ULARGE_INTEGER timeRight;
123 right.ToULargeInt(timeRight);
125 timeThis.QuadPart+=timeRight.QuadPart;
127 FromULargeInt(timeThis);
132 const CDateTimeSpan& CDateTimeSpan::operator -=(const CDateTimeSpan& right)
134 ULARGE_INTEGER timeThis;
135 ToULargeInt(timeThis);
137 ULARGE_INTEGER timeRight;
138 right.ToULargeInt(timeRight);
140 timeThis.QuadPart-=timeRight.QuadPart;
142 FromULargeInt(timeThis);
147 void CDateTimeSpan::ToULargeInt(ULARGE_INTEGER& time) const
149 time.u.HighPart=m_timeSpan.dwHighDateTime;
150 time.u.LowPart=m_timeSpan.dwLowDateTime;
153 void CDateTimeSpan::FromULargeInt(const ULARGE_INTEGER& time)
155 m_timeSpan.dwHighDateTime=time.u.HighPart;
156 m_timeSpan.dwLowDateTime=time.u.LowPart;
159 void CDateTimeSpan::SetDateTimeSpan(int day, int hour, int minute, int second)
164 time.QuadPart=(LONGLONG)day*SECONDS_PER_DAY*SECONDS_TO_FILETIME;
165 time.QuadPart+=(LONGLONG)hour*SECONDS_PER_HOUR*SECONDS_TO_FILETIME;
166 time.QuadPart+=(LONGLONG)minute*SECONDS_PER_MINUTE*SECONDS_TO_FILETIME;
167 time.QuadPart+=(LONGLONG)second*SECONDS_TO_FILETIME;
172 void CDateTimeSpan::SetFromTimeString(const CStdString& time) // hh:mm
174 int hour = atoi(time.Mid(0,2).c_str());
175 int minutes = atoi(time.Mid(3,2).c_str());
176 SetDateTimeSpan(0,hour,minutes,0);
179 int CDateTimeSpan::GetDays() const
184 return (int)(time.QuadPart/SECONDS_TO_FILETIME)/SECONDS_PER_DAY;
187 int CDateTimeSpan::GetHours() const
192 return (int)((time.QuadPart/SECONDS_TO_FILETIME)%SECONDS_PER_DAY)/SECONDS_PER_HOUR;
195 int CDateTimeSpan::GetMinutes() const
200 return (int)((time.QuadPart/SECONDS_TO_FILETIME%SECONDS_PER_DAY)%SECONDS_PER_HOUR)/SECONDS_PER_MINUTE;
203 int CDateTimeSpan::GetSeconds() const
208 return (int)(((time.QuadPart/SECONDS_TO_FILETIME%SECONDS_PER_DAY)%SECONDS_PER_HOUR)%SECONDS_PER_MINUTE)%SECONDS_PER_MINUTE;
211 void CDateTimeSpan::SetFromPeriod(const CStdString &period)
213 long days = atoi(period.c_str());
214 // find the first non-space and non-number
215 int pos = period.find_first_not_of("0123456789 ", 0);
218 CStdString units = period.Mid(pos, 3);
219 if (units.CompareNoCase("wee") == 0)
221 else if (units.CompareNoCase("mon") == 0)
225 SetDateTimeSpan(days, 0, 0, 0);
228 /////////////////////////////////////////////////
233 CDateTime::CDateTime()
238 CDateTime::CDateTime(const SYSTEMTIME &time)
240 // we store internally as a FILETIME
241 m_state = ToFileTime(time, m_time) ? valid : invalid;
244 CDateTime::CDateTime(const FILETIME &time)
250 CDateTime::CDateTime(const CDateTime& time)
253 m_state=time.m_state;
256 CDateTime::CDateTime(const time_t& time)
258 m_state = ToFileTime(time, m_time) ? valid : invalid;
261 CDateTime::CDateTime(const tm& time)
263 m_state = ToFileTime(time, m_time) ? valid : invalid;
266 CDateTime::CDateTime(int year, int month, int day, int hour, int minute, int second)
268 SetDateTime(year, month, day, hour, minute, second);
271 CDateTime CDateTime::GetCurrentDateTime()
273 // get the current time
277 return CDateTime(time);
280 CDateTime CDateTime::GetUTCDateTime()
282 TIME_ZONE_INFORMATION tz;
284 CDateTime time(GetCurrentDateTime());
285 switch(GetTimeZoneInformation(&tz))
287 case TIME_ZONE_ID_DAYLIGHT:
288 time += CDateTimeSpan(0, 0, tz.Bias + tz.DaylightBias, 0);
290 case TIME_ZONE_ID_STANDARD:
291 time += CDateTimeSpan(0, 0, tz.Bias + tz.StandardBias, 0);
293 case TIME_ZONE_ID_UNKNOWN:
294 time += CDateTimeSpan(0, 0, tz.Bias, 0);
301 const CDateTime& CDateTime::operator =(const SYSTEMTIME& right)
303 m_state = ToFileTime(right, m_time) ? valid : invalid;
308 const CDateTime& CDateTime::operator =(const FILETIME& right)
316 const CDateTime& CDateTime::operator =(const time_t& right)
318 m_state = ToFileTime(right, m_time) ? valid : invalid;
323 const CDateTime& CDateTime::operator =(const tm& right)
325 m_state = ToFileTime(right, m_time) ? valid : invalid;
330 bool CDateTime::operator >(const CDateTime& right) const
332 return operator >(right.m_time);
335 bool CDateTime::operator >=(const CDateTime& right) const
337 return operator >(right) || operator ==(right);
340 bool CDateTime::operator <(const CDateTime& right) const
342 return operator <(right.m_time);
345 bool CDateTime::operator <=(const CDateTime& right) const
347 return operator <(right) || operator ==(right);
350 bool CDateTime::operator ==(const CDateTime& right) const
352 return operator ==(right.m_time);
355 bool CDateTime::operator !=(const CDateTime& right) const
357 return !operator ==(right);
360 bool CDateTime::operator >(const FILETIME& right) const
362 return CompareFileTime(&m_time, &right)>0;
365 bool CDateTime::operator >=(const FILETIME& right) const
367 return operator >(right) || operator ==(right);
370 bool CDateTime::operator <(const FILETIME& right) const
372 return CompareFileTime(&m_time, &right)<0;
375 bool CDateTime::operator <=(const FILETIME& right) const
377 return operator <(right) || operator ==(right);
380 bool CDateTime::operator ==(const FILETIME& right) const
382 return CompareFileTime(&m_time, &right)==0;
385 bool CDateTime::operator !=(const FILETIME& right) const
387 return !operator ==(right);
390 bool CDateTime::operator >(const SYSTEMTIME& right) const
393 ToFileTime(right, time);
395 return operator >(time);
398 bool CDateTime::operator >=(const SYSTEMTIME& right) const
400 return operator >(right) || operator ==(right);
403 bool CDateTime::operator <(const SYSTEMTIME& right) const
406 ToFileTime(right, time);
408 return operator <(time);
411 bool CDateTime::operator <=(const SYSTEMTIME& right) const
413 return operator <(right) || operator ==(right);
416 bool CDateTime::operator ==(const SYSTEMTIME& right) const
419 ToFileTime(right, time);
421 return operator ==(time);
424 bool CDateTime::operator !=(const SYSTEMTIME& right) const
426 return !operator ==(right);
429 bool CDateTime::operator >(const time_t& right) const
432 ToFileTime(right, time);
434 return operator >(time);
437 bool CDateTime::operator >=(const time_t& right) const
439 return operator >(right) || operator ==(right);
442 bool CDateTime::operator <(const time_t& right) const
445 ToFileTime(right, time);
447 return operator <(time);
450 bool CDateTime::operator <=(const time_t& right) const
452 return operator <(right) || operator ==(right);
455 bool CDateTime::operator ==(const time_t& right) const
458 ToFileTime(right, time);
460 return operator ==(time);
463 bool CDateTime::operator !=(const time_t& right) const
465 return !operator ==(right);
468 bool CDateTime::operator >(const tm& right) const
471 ToFileTime(right, time);
473 return operator >(time);
476 bool CDateTime::operator >=(const tm& right) const
478 return operator >(right) || operator ==(right);
481 bool CDateTime::operator <(const tm& right) const
484 ToFileTime(right, time);
486 return operator <(time);
489 bool CDateTime::operator <=(const tm& right) const
491 return operator <(right) || operator ==(right);
494 bool CDateTime::operator ==(const tm& right) const
497 ToFileTime(right, time);
499 return operator ==(time);
502 bool CDateTime::operator !=(const tm& right) const
504 return !operator ==(right);
507 CDateTime CDateTime::operator +(const CDateTimeSpan& right) const
509 CDateTime left(*this);
511 ULARGE_INTEGER timeLeft;
512 left.ToULargeInt(timeLeft);
514 ULARGE_INTEGER timeRight;
515 right.ToULargeInt(timeRight);
517 timeLeft.QuadPart+=timeRight.QuadPart;
519 left.FromULargeInt(timeLeft);
524 CDateTime CDateTime::operator -(const CDateTimeSpan& right) const
526 CDateTime left(*this);
528 ULARGE_INTEGER timeLeft;
529 left.ToULargeInt(timeLeft);
531 ULARGE_INTEGER timeRight;
532 right.ToULargeInt(timeRight);
534 timeLeft.QuadPart-=timeRight.QuadPart;
536 left.FromULargeInt(timeLeft);
541 const CDateTime& CDateTime::operator +=(const CDateTimeSpan& right)
543 ULARGE_INTEGER timeThis;
544 ToULargeInt(timeThis);
546 ULARGE_INTEGER timeRight;
547 right.ToULargeInt(timeRight);
549 timeThis.QuadPart+=timeRight.QuadPart;
551 FromULargeInt(timeThis);
556 const CDateTime& CDateTime::operator -=(const CDateTimeSpan& right)
558 ULARGE_INTEGER timeThis;
559 ToULargeInt(timeThis);
561 ULARGE_INTEGER timeRight;
562 right.ToULargeInt(timeRight);
564 timeThis.QuadPart-=timeRight.QuadPart;
566 FromULargeInt(timeThis);
571 CDateTimeSpan CDateTime::operator -(const CDateTime& right) const
575 ULARGE_INTEGER timeLeft;
576 left.ToULargeInt(timeLeft);
578 ULARGE_INTEGER timeThis;
579 ToULargeInt(timeThis);
581 ULARGE_INTEGER timeRight;
582 right.ToULargeInt(timeRight);
584 timeLeft.QuadPart=timeThis.QuadPart-timeRight.QuadPart;
586 left.FromULargeInt(timeLeft);
591 CDateTime::operator FILETIME() const
596 void CDateTime::Archive(CArchive& ar)
613 m_state = CDateTime::STATE(state);
618 ToFileTime(st, m_time);
623 void CDateTime::Reset()
625 SetDateTime(1601, 1, 1, 0, 0, 0);
629 void CDateTime::SetValid(bool yesNo)
631 m_state=yesNo ? valid : invalid;
634 bool CDateTime::IsValid() const
636 return m_state==valid;
639 bool CDateTime::ToFileTime(const SYSTEMTIME& time, FILETIME& fileTime) const
641 return SystemTimeToFileTime(&time, &fileTime)==TRUE;
644 bool CDateTime::ToFileTime(const time_t& time, FILETIME& fileTime) const
646 LONGLONG ll = Int32x32To64(time, 10000000)+0x19DB1DED53E8000LL;
648 fileTime.dwLowDateTime = (DWORD)(ll & 0xFFFFFFFF);
649 fileTime.dwHighDateTime = (DWORD)(ll >> 32);
654 bool CDateTime::ToFileTime(const tm& time, FILETIME& fileTime) const
657 ZeroMemory(&st, sizeof(SYSTEMTIME));
659 st.wYear=time.tm_year+1900;
660 st.wMonth=time.tm_mon+1;
661 st.wDayOfWeek=time.tm_wday;
662 st.wDay=time.tm_mday;
663 st.wHour=time.tm_hour;
664 st.wMinute=time.tm_min;
665 st.wSecond=time.tm_sec;
667 return SystemTimeToFileTime(&st, &fileTime)==TRUE;
670 void CDateTime::ToULargeInt(ULARGE_INTEGER& time) const
672 time.u.HighPart=m_time.dwHighDateTime;
673 time.u.LowPart=m_time.dwLowDateTime;
676 void CDateTime::FromULargeInt(const ULARGE_INTEGER& time)
678 m_time.dwHighDateTime=time.u.HighPart;
679 m_time.dwLowDateTime=time.u.LowPart;
682 void CDateTime::SetFromDateString(const CStdString &date)
690 const char* months[] = {"january","february","march","april","may","june","july","august","september","october","november","december",NULL};
692 int iDayPos = date.Find("day");
693 int iPos = date.Find(" ");
694 if (iDayPos < iPos && iDayPos > -1)
697 iPos = date.Find(" ",iPos+1);
702 CStdString strMonth = date.Mid(iDayPos,iPos-iDayPos);
703 if (strMonth.IsEmpty()) // assume dbdate format
709 int iPos2 = date.Find(",");
710 CStdString strDay = date.Mid(iPos,iPos2-iPos);
711 CStdString strYear = date.Mid(date.Find(" ",iPos2)+1);
712 while (months[j] && stricmp(strMonth.c_str(),months[j]) != 0)
717 SetDateTime(atol(strYear.c_str()),j+1,atol(strDay.c_str()),0,0,0);
720 int CDateTime::GetDay() const
728 int CDateTime::GetMonth() const
736 int CDateTime::GetYear() const
744 int CDateTime::GetHour() const
752 int CDateTime::GetMinute() const
760 int CDateTime::GetSecond() const
768 int CDateTime::GetDayOfWeek() const
773 return st.wDayOfWeek;
776 int CDateTime::GetMinuteOfDay() const
780 return st.wHour*60+st.wMinute;
783 void CDateTime::SetDateTime(int year, int month, int day, int hour, int minute, int second)
786 ZeroMemory(&st, sizeof(SYSTEMTIME));
795 m_state = ToFileTime(st, m_time) ? valid : invalid;
798 void CDateTime::SetDate(int year, int month, int day)
800 SetDateTime(year, month, day, 0, 0, 0);
803 void CDateTime::SetTime(int hour, int minute, int second)
805 // 01.01.1601 00:00:00 is 0 as filetime
806 SetDateTime(1601, 1, 1, hour, minute, second);
809 void CDateTime::GetAsSystemTime(SYSTEMTIME& time) const
811 FileTimeToSystemTime(&m_time, &time);
814 #define UNIX_BASE_TIME 116444736000000000LL /* nanoseconds since epoch */
815 void CDateTime::GetAsTime(time_t& time) const
818 ll = ((LONGLONG)m_time.dwHighDateTime << 32) + m_time.dwLowDateTime;
819 time=(time_t)((ll - UNIX_BASE_TIME) / 10000000);
822 void CDateTime::GetAsTm(tm& time) const
827 time.tm_year=st.wYear-1900;
828 time.tm_mon=st.wMonth-1;
829 time.tm_wday=st.wDayOfWeek;
830 time.tm_mday=st.wDay;
831 time.tm_hour=st.wHour;
832 time.tm_min=st.wMinute;
833 time.tm_sec=st.wSecond;
838 void CDateTime::GetAsTimeStamp(FILETIME& time) const
840 ::LocalFileTimeToFileTime(&m_time, &time);
843 CStdString CDateTime::GetAsDBDate() const
849 date.Format("%04i-%02i-%02i", st.wYear, st.wMonth, st.wDay);
854 CStdString CDateTime::GetAsDBDateTime() const
860 date.Format("%04i-%02i-%02i %02i:%02i:%02i", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
865 void CDateTime::SetFromW3CDate(const CStdString &dateTime)
867 CStdString date, time, zone;
869 int posT = dateTime.Find("T");
872 date = dateTime.Left(posT);
873 CStdString::size_type posZ = dateTime.find_first_of("+-Z", posT);
874 if(posZ == CStdString::npos)
875 time = dateTime.Mid(posT+1);
878 time = dateTime.Mid(posT+1, posZ-posT-1);
879 zone = dateTime.Mid(posZ);
885 int year = 0, month = 1, day = 1, hour = 0, min = 0, sec = 0;
887 if (date.size() >= 4)
888 year = atoi(date.Mid(0,4).c_str());
890 if (date.size() >= 10)
892 month = atoi(date.Mid(5,2).c_str());
893 day = atoi(date.Mid(8,2).c_str());
896 if (time.length() >= 5)
898 hour = atoi(time.Mid(0,2).c_str());
899 min = atoi(time.Mid(3,2).c_str());
902 if (time.length() >= 8)
903 sec = atoi(time.Mid(6,2).c_str());
905 SetDateTime(year, month, day, hour, min, sec);
908 void CDateTime::SetFromDBDateTime(const CStdString &dateTime)
910 // assumes format YYYY-MM-DD HH:MM:SS
911 if (dateTime.size() == 19)
913 int year = atoi(dateTime.Mid(0,4).c_str());
914 int month = atoi(dateTime.Mid(5,2).c_str());
915 int day = atoi(dateTime.Mid(8,2).c_str());
916 int hour = atoi(dateTime.Mid(11,2).c_str());
917 int min = atoi(dateTime.Mid(14,2).c_str());
918 int sec = atoi(dateTime.Mid(17,2).c_str());
919 SetDateTime(year, month, day, hour, min, sec);
923 void CDateTime::SetFromDBDate(const CStdString &date)
926 // YYYY-MM-DD or DD-MM-YYYY
927 int year = 0, month = 0, day = 0;
928 if (date.size() > 2 && (date[2] == '-' || date[2] == '.'))
930 day = atoi(date.Mid(0,2).c_str());
931 month = atoi(date.Mid(3,2).c_str());
932 year = atoi(date.Mid(6,4).c_str());
936 year = atoi(date.Mid(0,4).c_str());
937 month = atoi(date.Mid(5,2).c_str());
938 day = atoi(date.Mid(8,2).c_str());
940 SetDate(year, month, day);
943 void CDateTime::SetFromDBTime(const CStdString &time)
947 int hour, minute, second;
949 hour = atoi(time.Mid(0,2).c_str());
950 minute = atoi(time.Mid(3,2).c_str());
951 second = atoi(time.Mid(6,2).c_str());
953 SetTime(hour, minute, second);
956 CStdString CDateTime::GetAsLocalizedTime(const CStdString &format, bool withSeconds) const
959 const CStdString& strFormat = format.IsEmpty() ? g_langInfo.GetTimeFormat() : format;
962 GetAsSystemTime(dateTime);
964 // Prefetch meridiem symbol
965 const CStdString& strMeridiem=g_langInfo.GetMeridiemSymbol(dateTime.wHour > 11 ? CLangInfo::MERIDIEM_SYMBOL_PM : CLangInfo::MERIDIEM_SYMBOL_AM);
967 int length=strFormat.GetLength();
968 for (int i=0; i<length; ++i)
973 // To be able to display a "'" in the string,
974 // find the last "'" that doesn't follow a "'"
976 while(((pos=strFormat.Find(c,pos+1))>-1 && pos<strFormat.GetLength()) && strFormat[pos+1]=='\'') {}
981 // Extract string between ' '
982 strPart=strFormat.Mid(i+1, pos-i-1);
987 strPart=strFormat.Mid(i+1, length-i-1);
991 strPart.Replace("''", "'");
995 else if (c=='h' || c=='H') // parse hour (H="24 hour clock")
999 int pos=strFormat.find_first_not_of(c,i+1);
1002 // Get length of the hour mask, eg. HH
1008 // mask ends at the end of the string, extract it
1009 partLength=length-i;
1013 int hour=dateTime.wHour;
1015 { // recalc to 12 hour clock
1017 hour -= (12 * (hour > 12));
1019 hour += (12 * (hour < 1));
1022 // Format hour string with the length of the mask
1025 str.Format("%d", hour);
1027 str.Format("%02d", hour);
1031 else if (c=='m') // parse minutes
1035 int pos=strFormat.find_first_not_of(c,i+1);
1038 // Get length of the minute mask, eg. mm
1044 // mask ends at the end of the string, extract it
1045 partLength=length-i;
1049 // Format minute string with the length of the mask
1052 str.Format("%d", dateTime.wMinute);
1054 str.Format("%02d", dateTime.wMinute);
1058 else if (c=='s') // parse seconds
1062 int pos=strFormat.find_first_not_of(c,i+1);
1065 // Get length of the seconds mask, eg. ss
1071 // mask ends at the end of the string, extract it
1072 partLength=length-i;
1078 // Format seconds string with the length of the mask
1081 str.Format("%d", dateTime.wSecond);
1083 str.Format("%02d", dateTime.wSecond);
1088 strOut.Delete(strOut.GetLength()-1,1);
1090 else if (c=='x') // add meridiem symbol
1094 int pos=strFormat.find_first_not_of(c,i+1);
1097 // Get length of the meridiem mask
1103 // mask ends at the end of the string, extract it
1104 partLength=length-i;
1108 strOut+=strMeridiem;
1110 else // everything else pass to output
1117 CStdString CDateTime::GetAsLocalizedDate(bool longDate/*=false*/, bool withShortNames/*=true*/) const
1121 const CStdString& strFormat=g_langInfo.GetDateFormat(longDate);
1123 SYSTEMTIME dateTime;
1124 GetAsSystemTime(dateTime);
1126 int length=strFormat.GetLength();
1128 for (int i=0; i<length; ++i)
1130 char c=strFormat[i];
1133 // To be able to display a "'" in the string,
1134 // find the last "'" that doesn't follow a "'"
1136 while(((pos=strFormat.Find(c,pos+1))>-1 && pos<strFormat.GetLength()) && strFormat[pos+1]=='\'') {}
1141 // Extract string between ' '
1142 strPart=strFormat.Mid(i+1, pos-i-1);
1147 strPart=strFormat.Mid(i+1, length-i-1);
1150 strPart.Replace("''", "'");
1153 else if (c=='D') // parse days
1157 int pos=strFormat.find_first_not_of(c,i+1);
1160 // Get length of the day mask, eg. DDDD
1166 // mask ends at the end of the string, extract it
1167 partLength=length-i;
1171 // Format string with the length of the mask
1173 if (partLength==1) // single-digit number
1174 str.Format("%d", dateTime.wDay);
1175 else if (partLength==2) // two-digit number
1176 str.Format("%02d", dateTime.wDay);
1177 else // Day of week string
1179 int wday = dateTime.wDayOfWeek;
1180 if (wday < 1 || wday > 7) wday = 7;
1181 str = g_localizeStrings.Get((withShortNames ? 40 : 10) + wday);
1185 else if (c=='M') // parse month
1189 int pos=strFormat.find_first_not_of(c,i+1);
1192 // Get length of the month mask, eg. MMMM
1198 // mask ends at the end of the string, extract it
1199 partLength=length-i;
1203 // Format string with the length of the mask
1205 if (partLength==1) // single-digit number
1206 str.Format("%d", dateTime.wMonth);
1207 else if (partLength==2) // two-digit number
1208 str.Format("%02d", dateTime.wMonth);
1209 else // Month string
1211 int wmonth = dateTime.wMonth;
1212 if (wmonth < 1 || wmonth > 12) wmonth = 12;
1213 str = g_localizeStrings.Get((withShortNames ? 50 : 20) + wmonth);
1217 else if (c=='Y') // parse year
1221 int pos=strFormat.find_first_not_of(c,i+1);
1224 // Get length of the year mask, eg. YYYY
1230 // mask ends at the end of the string, extract it
1231 partLength=length-i;
1235 // Format string with the length of the mask
1237 str.Format("%d", dateTime.wYear); // four-digit number
1239 str.Delete(0, 2); // two-digit number
1243 else // everything else pass to output
1250 CStdString CDateTime::GetAsLocalizedDateTime(bool longDate/*=false*/, bool withSeconds/*=true*/) const
1252 return GetAsLocalizedDate(longDate)+" "+GetAsLocalizedTime("", withSeconds);
1255 CDateTime CDateTime::GetAsUTCDateTime() const
1257 TIME_ZONE_INFORMATION tz;
1259 CDateTime time(m_time);
1260 switch(GetTimeZoneInformation(&tz))
1262 case TIME_ZONE_ID_DAYLIGHT:
1263 time += CDateTimeSpan(0, 0, tz.Bias + tz.DaylightBias, 0);
1265 case TIME_ZONE_ID_STANDARD:
1266 time += CDateTimeSpan(0, 0, tz.Bias + tz.StandardBias, 0);
1268 case TIME_ZONE_ID_UNKNOWN:
1269 time += CDateTimeSpan(0, 0, tz.Bias, 0);
1276 static const char *DAY_NAMES[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
1277 static const char *MONTH_NAMES[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
1279 CStdString CDateTime::GetAsRFC1123DateTime() const
1281 CDateTime time(GetAsUTCDateTime());
1283 result.Format("%s, %02i %s %04i %02i:%02i:%02i GMT", DAY_NAMES[time.GetDayOfWeek()], time.GetDay(), MONTH_NAMES[time.GetMonth()-1], time.GetYear(), time.GetHour(), time.GetMinute(), time.GetSecond());