1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "utils/IArchivable.h"
12 #include "utils/XTimeUtils.h"
13 
14 #include <string>
15 
16 #include "PlatformDefs.h"
17 
18 /*! \brief TIME_FORMAT enum/bitmask used for formatting time strings
19  Note the use of bitmasking, e.g.
20   TIME_FORMAT_HH_MM_SS = TIME_FORMAT_HH | TIME_FORMAT_MM | TIME_FORMAT_SS
21  \sa StringUtils::SecondsToTimeString
22  \note For InfoLabels use the equivalent value listed (bold)
23   on the description of each enum value.
24  \note<b>Example:</b> 3661 seconds => h=1, hh=01, m=1, mm=01, ss=01, hours=1, mins=61, secs=3661
25  <p><hr>
26  @skinning_v18 **[Infolabels Updated]** Added <b>secs</b>, <b>mins</b>, <b>hours</b> (total time) and **m** as possible formats for
27  InfoLabels that support the definition of a time format. Examples are:
28    - \link Player_SeekOffset_format `Player.SeekOffset(format)`\endlink
29    - \link Player_TimeRemaining_format `Player.TimeRemaining(format)`\endlink
30    - \link Player_Time_format `Player.Time(format)`\endlink
31    - \link Player_Duration_format `Player.Duration(format)`\endlink
32    - \link Player_FinishTime_format `Player.FinishTime(format)`\endlink
33    - \link Player_StartTime_format `Player.StartTime(format)` \endlink
34    - \link Player_SeekNumeric_format `Player.SeekNumeric(format)`\endlink
35    - \link ListItem_Duration_format `ListItem.Duration(format)`\endlink
36    - \link PVR_EpgEventDuration_format `PVR.EpgEventDuration(format)`\endlink
37    - \link PVR_EpgEventElapsedTime_format `PVR.EpgEventElapsedTime(format)`\endlink
38    - \link PVR_EpgEventRemainingTime_format `PVR.EpgEventRemainingTime(format)`\endlink
39    - \link PVR_EpgEventSeekTime_format `PVR.EpgEventSeekTime(format)`\endlink
40    - \link PVR_EpgEventFinishTime_format `PVR.EpgEventFinishTime(format)`\endlink
41    - \link PVR_TimeShiftStart_format `PVR.TimeShiftStart(format)`\endlink
42    - \link PVR_TimeShiftEnd_format `PVR.TimeShiftEnd(format)`\endlink
43    - \link PVR_TimeShiftCur_format `PVR.TimeShiftCur(format)`\endlink
44    - \link PVR_TimeShiftOffset_format `PVR.TimeShiftOffset(format)`\endlink
45    - \link PVR_TimeshiftProgressDuration_format `PVR.TimeshiftProgressDuration(format)`\endlink
46    - \link PVR_TimeshiftProgressEndTime `PVR.TimeshiftProgressEndTime`\endlink
47    - \link PVR_TimeshiftProgressEndTime_format `PVR.TimeshiftProgressEndTime(format)`\endlink
48    - \link ListItem_NextDuration_format `ListItem.NextDuration(format)` \endlink
49   <p>
50  */
51 enum TIME_FORMAT
52 {
53   TIME_FORMAT_GUESS = 0, ///< usually used as the fallback value if the format value is empty
54   TIME_FORMAT_SS = 1, ///< <b>ss</b> - seconds only
55   TIME_FORMAT_MM = 2, ///< <b>mm</b> - minutes only (2-digit)
56   TIME_FORMAT_MM_SS = 3, ///< <b>mm:ss</b> - minutes and seconds
57   TIME_FORMAT_HH = 4, ///< <b>hh</b> - hours only (2-digit)
58   TIME_FORMAT_HH_SS = 5, ///< <b>hh:ss</b> - hours and seconds (this is not particularly useful)
59   TIME_FORMAT_HH_MM = 6, ///< <b>hh:mm</b> - hours and minutes
60   TIME_FORMAT_HH_MM_SS = 7, ///< <b>hh:mm:ss</b> - hours, minutes and seconds
61   TIME_FORMAT_XX = 8, ///<  <b>xx</b> - returns AM/PM for a 12-hour clock
62   TIME_FORMAT_HH_MM_XX =
63       14, ///< <b>hh:mm xx</b> - returns hours and minutes in a 12-hour clock format (AM/PM)
64   TIME_FORMAT_HH_MM_SS_XX =
65       15, ///< <b>hh:mm:ss xx</b> - returns hours (2-digit), minutes and seconds in a 12-hour clock format (AM/PM)
66   TIME_FORMAT_H = 16, ///< <b>h</b> - hours only (1-digit)
67   TIME_FORMAT_H_MM_SS = 19, ///< <b>hh:mm:ss</b> - hours, minutes and seconds
68   TIME_FORMAT_H_MM_SS_XX =
69       27, ///< <b>hh:mm:ss xx</b> - returns hours (1-digit), minutes and seconds in a 12-hour clock format (AM/PM)
70   TIME_FORMAT_SECS = 32, ///<  <b>secs</b> - total time in seconds
71   TIME_FORMAT_MINS = 64, ///<  <b>mins</b> - total time in minutes
72   TIME_FORMAT_HOURS = 128, ///< <b>hours</b> - total time in hours
73   TIME_FORMAT_M = 256 ///< <b>m</b> - minutes only (1-digit)
74 };
75 
76 class CDateTime;
77 
78 class CDateTimeSpan
79 {
80 public:
81   CDateTimeSpan();
82   CDateTimeSpan(const CDateTimeSpan& span);
83   CDateTimeSpan(int day, int hour, int minute, int second);
84 
85   bool operator >(const CDateTimeSpan& right) const;
86   bool operator >=(const CDateTimeSpan& right) const;
87   bool operator <(const CDateTimeSpan& right) const;
88   bool operator <=(const CDateTimeSpan& right) const;
89   bool operator ==(const CDateTimeSpan& right) const;
90   bool operator !=(const CDateTimeSpan& right) const;
91 
92   CDateTimeSpan operator +(const CDateTimeSpan& right) const;
93   CDateTimeSpan operator -(const CDateTimeSpan& right) const;
94 
95   const CDateTimeSpan& operator +=(const CDateTimeSpan& right);
96   const CDateTimeSpan& operator -=(const CDateTimeSpan& right);
97 
98   void SetDateTimeSpan(int day, int hour, int minute, int second);
99   void SetFromPeriod(const std::string &period);
100   void SetFromTimeString(const std::string& time);
101 
102   int GetDays() const;
103   int GetHours() const;
104   int GetMinutes() const;
105   int GetSeconds() const;
106   int GetSecondsTotal() const;
107 
108 private:
109   void ToLargeInt(LARGE_INTEGER& time) const;
110   void FromLargeInt(const LARGE_INTEGER& time);
111 
112 private:
113   KODI::TIME::FileTime m_timeSpan;
114 
115   friend class CDateTime;
116 };
117 
118 /// \brief DateTime class, which uses FileTime as it's base.
119 class CDateTime final : public IArchivable
120 {
121 public:
122   CDateTime();
123   CDateTime(const CDateTime& time);
124   explicit CDateTime(const KODI::TIME::SystemTime& time);
125   explicit CDateTime(const KODI::TIME::FileTime& time);
126   explicit CDateTime(const time_t& time);
127   explicit CDateTime(const tm& time);
128   CDateTime(int year, int month, int day, int hour, int minute, int second);
129 
130   static CDateTime GetCurrentDateTime();
131   static CDateTime GetUTCDateTime();
132   static int MonthStringToMonthNum(const std::string& month);
133 
134   static CDateTime FromDBDateTime(const std::string &dateTime);
135   static CDateTime FromDateString(const std::string &date);
136   static CDateTime FromDBDate(const std::string &date);
137   static CDateTime FromDBTime(const std::string &time);
138   static CDateTime FromW3CDate(const std::string &date);
139   static CDateTime FromW3CDateTime(const std::string &date, bool ignoreTimezone = false);
140   static CDateTime FromUTCDateTime(const CDateTime &dateTime);
141   static CDateTime FromUTCDateTime(const time_t &dateTime);
142   static CDateTime FromRFC1123DateTime(const std::string &dateTime);
143 
144   const CDateTime& operator=(const KODI::TIME::SystemTime& right);
145   const CDateTime& operator=(const KODI::TIME::FileTime& right);
146   const CDateTime& operator =(const time_t& right);
147   const CDateTime& operator =(const tm& right);
148 
149   bool operator >(const CDateTime& right) const;
150   bool operator >=(const CDateTime& right) const;
151   bool operator <(const CDateTime& right) const;
152   bool operator <=(const CDateTime& right) const;
153   bool operator ==(const CDateTime& right) const;
154   bool operator !=(const CDateTime& right) const;
155 
156   bool operator>(const KODI::TIME::FileTime& right) const;
157   bool operator>=(const KODI::TIME::FileTime& right) const;
158   bool operator<(const KODI::TIME::FileTime& right) const;
159   bool operator<=(const KODI::TIME::FileTime& right) const;
160   bool operator==(const KODI::TIME::FileTime& right) const;
161   bool operator!=(const KODI::TIME::FileTime& right) const;
162 
163   bool operator>(const KODI::TIME::SystemTime& right) const;
164   bool operator>=(const KODI::TIME::SystemTime& right) const;
165   bool operator<(const KODI::TIME::SystemTime& right) const;
166   bool operator<=(const KODI::TIME::SystemTime& right) const;
167   bool operator==(const KODI::TIME::SystemTime& right) const;
168   bool operator!=(const KODI::TIME::SystemTime& right) const;
169 
170   bool operator >(const time_t& right) const;
171   bool operator >=(const time_t& right) const;
172   bool operator <(const time_t& right) const;
173   bool operator <=(const time_t& right) const;
174   bool operator ==(const time_t& right) const;
175   bool operator !=(const time_t& right) const;
176 
177   bool operator >(const tm& right) const;
178   bool operator >=(const tm& right) const;
179   bool operator <(const tm& right) const;
180   bool operator <=(const tm& right) const;
181   bool operator ==(const tm& right) const;
182   bool operator !=(const tm& right) const;
183 
184   CDateTime operator +(const CDateTimeSpan& right) const;
185   CDateTime operator -(const CDateTimeSpan& right) const;
186 
187   const CDateTime& operator +=(const CDateTimeSpan& right);
188   const CDateTime& operator -=(const CDateTimeSpan& right);
189 
190   CDateTimeSpan operator -(const CDateTime& right) const;
191 
192   operator KODI::TIME::FileTime() const;
193 
194   void Archive(CArchive& ar) override;
195 
196   void Reset();
197 
198   int GetDay() const;
199   int GetMonth() const;
200   int GetYear() const;
201   int GetHour() const;
202   int GetMinute() const;
203   int GetSecond() const;
204   int GetDayOfWeek() const;
205   int GetMinuteOfDay() const;
206 
207   bool SetDateTime(int year, int month, int day, int hour, int minute, int second);
208   bool SetDate(int year, int month, int day);
209   bool SetTime(int hour, int minute, int second);
210 
211   bool SetFromDateString(const std::string &date);
212   bool SetFromDBDate(const std::string &date);
213   bool SetFromDBTime(const std::string &time);
214   bool SetFromW3CDate(const std::string &date);
215   bool SetFromW3CDateTime(const std::string &date, bool ignoreTimezone = false);
216   bool SetFromUTCDateTime(const CDateTime &dateTime);
217   bool SetFromUTCDateTime(const time_t &dateTime);
218   bool SetFromRFC1123DateTime(const std::string &dateTime);
219 
220   /*! \brief set from a database datetime format YYYY-MM-DD HH:MM:SS
221    \sa GetAsDBDateTime()
222    */
223   bool SetFromDBDateTime(const std::string &dateTime);
224 
225   void GetAsSystemTime(KODI::TIME::SystemTime& time) const;
226   void GetAsTime(time_t& time) const;
227   void GetAsTm(tm& time) const;
228   void GetAsTimeStamp(KODI::TIME::FileTime& time) const;
229 
230   CDateTime GetAsUTCDateTime() const;
231   std::string GetAsSaveString() const;
232   std::string GetAsDBDateTime() const;
233   std::string GetAsDBDate() const;
234   std::string GetAsDBTime() const;
235   std::string GetAsLocalizedDate(bool longDate=false) const;
236   std::string GetAsLocalizedDate(const std::string &strFormat) const;
237   std::string GetAsLocalizedTime(const std::string &format, bool withSeconds=true) const;
238   std::string GetAsLocalizedDateTime(bool longDate=false, bool withSeconds=true) const;
239   std::string GetAsLocalizedTime(TIME_FORMAT format, bool withSeconds = false) const;
240   std::string GetAsRFC1123DateTime() const;
241   std::string GetAsW3CDate() const;
242   std::string GetAsW3CDateTime(bool asUtc = false) const;
243 
244   void SetValid(bool yesNo);
245   bool IsValid() const;
246 
247   static void ResetTimezoneBias(void);
248   static CDateTimeSpan GetTimezoneBias(void);
249 
250 private:
251   bool ToFileTime(const KODI::TIME::SystemTime& time, KODI::TIME::FileTime& fileTime) const;
252   bool ToFileTime(const time_t& time, KODI::TIME::FileTime& fileTime) const;
253   bool ToFileTime(const tm& time, KODI::TIME::FileTime& fileTime) const;
254 
255   void ToLargeInt(LARGE_INTEGER& time) const;
256   void FromLargeInt(const LARGE_INTEGER& time);
257 
258 private:
259   KODI::TIME::FileTime m_time;
260 
261   typedef enum _STATE
262   {
263     invalid=0,
264     valid
265   } STATE;
266 
267   STATE m_state;
268 };
269