VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gdate.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gdate.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gdate.h"
23 #include "gdebug.h"
24 #include <ctime>
25 #include <iomanip>
26 #include <sstream>
27 
29 {
30  return 2035 ; // see mktime()
31 }
32 
34 {
35  return 1970 ; // see mktime()
36 }
37 
39 {
41 }
42 
44 {
45  init( G::DateTime::utc(t) ) ;
46 }
47 
49 {
50  init( G::DateTime::local(t) ) ;
51 }
52 
53 G::Date::Date( const G::DateTime::BrokenDownTime & tm )
54 {
55  init( tm ) ;
56 }
57 
59 {
61 }
62 
63 G::Date::Date( int year , G::Date::Month month , int day_of_month )
64 {
65  G_ASSERT( year >= yearLowerLimit() ) ;
66  G_ASSERT( year <= yearUpperLimit() ) ;
67  m_year = year ;
68 
69  G_ASSERT( day_of_month > 0 ) ;
70  G_ASSERT( day_of_month < 32 ) ;
71  m_day = day_of_month ;
72 
73  G_ASSERT( month >= 1 ) ;
74  G_ASSERT( month <= 12 ) ;
75  m_month = month ;
76 
77  m_weekday_set = false ;
78 }
79 
80 void G::Date::init( const G::DateTime::BrokenDownTime & tm )
81 {
82  m_year = tm.tm_year + 1900 ;
83  m_month = tm.tm_mon + 1 ;
84  m_day = tm.tm_mday ;
85  m_weekday_set = false ;
86  m_weekday = sunday ;
87 }
88 
89 std::string G::Date::string( Format format ) const
90 {
91  std::ostringstream ss ;
92  if( format == yyyy_mm_dd_slash )
93  {
94  ss << yyyy() << "/" << mm() << "/" << dd() ;
95  }
96  else if( format == yyyy_mm_dd )
97  {
98  ss << yyyy() << mm() << dd() ;
99  }
100  else if( format == mm_dd )
101  {
102  ss << mm() << dd() ;
103  }
104  else
105  {
106  G_ASSERT( "enum error" == 0 ) ;
107  }
108  return ss.str() ;
109 }
110 
111 int G::Date::monthday() const
112 {
113  return m_day ;
114 }
115 
116 std::string G::Date::dd() const
117 {
118  std::ostringstream ss ;
119  ss << std::setw(2) << std::setfill('0') << m_day ;
120  return ss.str() ;
121 }
122 
123 std::string G::Date::mm() const
124 {
125  std::ostringstream ss ;
126  ss << std::setw(2) << std::setfill('0') << m_month ;
127  return ss.str() ;
128 }
129 
130 G::Date::Weekday G::Date::weekday() const
131 {
132  if( ! m_weekday_set )
133  {
134  G::DateTime::BrokenDownTime tm ;
135  tm.tm_year = m_year - 1900 ;
136  tm.tm_mon = m_month - 1 ;
137  tm.tm_mday = m_day ;
138  tm.tm_hour = 12 ;
139  tm.tm_min = 0 ;
140  tm.tm_sec = 0 ;
141  tm.tm_wday = 0 ; // ignored
142  tm.tm_yday = 0 ; // ignored
143  tm.tm_isdst = 0 ; // ignored
144 
145  G::DateTime::BrokenDownTime out = G::DateTime::utc(G::DateTime::epochTime(tm)) ;
146 
147  const_cast<Date*>(this)->m_weekday_set = true ;
148  const_cast<Date*>(this)->m_weekday = Weekday(out.tm_wday) ;
149  }
150  return m_weekday ;
151 }
152 
153 std::string G::Date::weekdayName( bool brief ) const
154 {
155  if( weekday() == sunday ) return brief ? "Sun" : "Sunday" ;
156  if( weekday() == monday ) return brief ? "Mon" : "Monday" ;
157  if( weekday() == tuesday ) return brief ? "Tue" : "Tuesday" ;
158  if( weekday() == wednesday ) return brief ? "Wed" : "Wednesday" ;
159  if( weekday() == thursday ) return brief ? "Thu" : "Thursday" ;
160  if( weekday() == friday ) return brief ? "Fri" : "Friday" ;
161  if( weekday() == saturday ) return brief ? "Sat" : "Saturday" ;
162  return "" ;
163 }
164 
165 G::Date::Month G::Date::month() const
166 {
167  return Month(m_month) ;
168 }
169 
170 std::string G::Date::monthName( bool brief ) const
171 {
172  if( month() == january ) return brief ? "Jan" : "January" ;
173  if( month() == february ) return brief ? "Feb" : "February" ;
174  if( month() == march ) return brief ? "Mar" : "March" ;
175  if( month() == april ) return brief ? "Apr" : "April" ;
176  if( month() == may ) return brief ? "May" : "May" ;
177  if( month() == june ) return brief ? "Jun" : "June" ;
178  if( month() == july ) return brief ? "Jul" : "July" ;
179  if( month() == august ) return brief ? "Aug" : "August" ;
180  if( month() == september ) return brief ? "Sep" : "September" ;
181  if( month() == october ) return brief ? "Oct" : "October" ;
182  if( month() == november ) return brief ? "Nov" : "November" ;
183  if( month() == december ) return brief ? "Dec" : "December" ;
184  return "" ;
185 }
186 
187 int G::Date::year() const
188 {
189  return m_year ;
190 }
191 
192 std::string G::Date::yyyy() const
193 {
194  std::ostringstream ss ;
195  ss << std::setw(4) << std::setfill('0') << m_year ;
196  return ss.str() ;
197 }
198 
200 {
201  ++m_day ;
202  if( m_day == (lastDay(m_month,m_year)+1) )
203  {
204  m_day = 1 ;
205  ++m_month ;
206  if( m_month == 13 )
207  {
208  m_month = 1 ;
209  ++m_year ;
210  }
211  }
212  if( m_weekday_set )
213  {
214  if( m_weekday == saturday )
215  m_weekday = sunday ;
216  else
217  m_weekday = Weekday(int(m_weekday)+1) ;
218  }
219  return *this ;
220 }
221 
223 {
224  if( m_day == 1 )
225  {
226  if( m_month == 1 )
227  {
228  m_year-- ;
229  m_month = 12 ;
230  }
231  else
232  {
233  m_month-- ;
234  }
235 
236  m_day = lastDay( m_month , m_year ) ;
237  }
238  else
239  {
240  m_day-- ;
241  }
242  if( m_weekday_set )
243  {
244  if( m_weekday == sunday )
245  m_weekday = saturday ;
246  else
247  m_weekday = Weekday(int(m_weekday)-1) ;
248  }
249  return *this ;
250 }
251 
252 int G::Date::lastDay( int month , int year )
253 {
254  int end = 30 ;
255  if( month == 1 ||
256  month == 3 ||
257  month == 5 ||
258  month == 7 ||
259  month == 8 ||
260  month == 10 ||
261  month == 12 )
262  {
263  end = 31 ;
264  }
265  else if( month == 2 )
266  {
267  end = isLeapYear(year) ? 29 : 28 ;
268  }
269  return end ;
270 }
271 
272 bool G::Date::isLeapYear( int y )
273 {
274  return y >= 1800 && ( y % 400 == 0 || ( y % 100 != 0 && y % 4 == 0 ) ) ;
275 }
276 
277 bool G::Date::operator==( const Date &other ) const
278 {
279  return
280  year() == other.year() &&
281  month() == other.month() &&
282  monthday() == other.monthday() ;
283 }
284 
285 bool G::Date::operator!=( const Date &other ) const
286 {
287  return !( other == *this ) ;
288 }
289 
290 /// \file gdate.cpp
static BrokenDownTime utc(EpochTime epoch_time)
Converts from epoch time to UTC broken-down-time.
Definition: gdatetime.cpp:123
A subsecond-resolution timestamp based on a time_t.
Definition: gdatetime.h:39
Month month() const
Returns the month.
Definition: gdate.cpp:165
A date (dd/mm/yyyy) class.
Definition: gdate.h:39
std::string monthName(bool brief=false) const
Returns the month as a string (in english).
Definition: gdate.cpp:170
static int yearLowerLimit()
Returns the smallest supported year value.
Definition: gdate.cpp:33
static BrokenDownTime local(EpochTime epoch_time)
Converts from epoch time to local broken-down-time.
Definition: gdatetime.cpp:131
bool operator!=(const Date &rhs) const
Comparison operator.
Definition: gdate.cpp:285
int monthday() const
Returns the day of the month.
Definition: gdate.cpp:111
int year() const
Returns the year.
Definition: gdate.cpp:187
bool operator==(const Date &rhs) const
Comparison operator.
Definition: gdate.cpp:277
static EpochTime now()
Returns the current epoch time.
An overload discriminator class for Date constructors.
Definition: gdate.h:42
std::string string(Format format=yyyy_mm_dd_slash) const
Returns a string representation of the date.
Definition: gdate.cpp:89
std::string dd() const
Returns the day of the month as a two-digit decimal string.
Definition: gdate.cpp:116
Date()
Default constructor for the current date in the UTC timezone.
Definition: gdate.cpp:38
std::string yyyy() const
Returns the year as a four-digit decimal string.
Definition: gdate.cpp:192
std::string weekdayName(bool brief=false) const
Returns an english string representation of the day of the week.
Definition: gdate.cpp:153
Date & operator--()
Decrements the date by one day.
Definition: gdate.cpp:222
Date & operator++()
Increments the date by one day.
Definition: gdate.cpp:199
Weekday weekday() const
Returns the day of the week.
Definition: gdate.cpp:130
static int yearUpperLimit()
Returns the largest supported year value.
Definition: gdate.cpp:28
static EpochTime epochTime(const BrokenDownTime &broken_down_time)
Converts from UTC broken-down-time to epoch time.
Definition: gdatetime.cpp:83
std::string mm() const
Returns the month as a two-digit decimal string.
Definition: gdate.cpp:123