E-MailRelay

gdate.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 Graeme Walker <graeme_walker@users.sourceforge.net>
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/// \file gdate.cpp
19///
20
21#include "gdef.h"
22#include "gdate.h"
23#include "glog.h"
24#include "gassert.h"
25#include <ctime>
26#include <iomanip>
27#include <sstream>
28
29 int G::Date::yearUpperLimit()
30{
31 return 2035 ; // see mktime()
32}
33
34 int G::Date::yearLowerLimit()
35{
36 return 1970 ; // see mktime()
37}
38
39 G::Date::Date()
40{
41 init( SystemTime::now().utc() ) ;
42}
43
44 G::Date::Date( SystemTime t )
45{
46 init( t.utc() ) ;
47}
48
49 G::Date::Date( SystemTime t , const LocalTime & )
50{
51 init( t.local() ) ;
52}
53
54 G::Date::Date( const BrokenDownTime & tm )
55{
56 init( tm ) ;
57}
58
59 G::Date::Date( const LocalTime & )
60{
61 init( SystemTime::now().local() ) ;
62}
63
64 G::Date::Date( int year , Date::Month month , int day_of_month ) :
65 m_day(day_of_month) ,
66 m_month(static_cast<int>(month)) ,
67 m_year(year)
68{
69 G_ASSERT( year >= yearLowerLimit() ) ;
70 G_ASSERT( year <= yearUpperLimit() ) ;
71 G_ASSERT( day_of_month > 0 ) ;
72 G_ASSERT( day_of_month < 32 ) ;
73 G_ASSERT( static_cast<int>(month) >= 1 ) ;
74 G_ASSERT( static_cast<int>(month) <= 12 ) ;
75}
76
77 void G::Date::init( const BrokenDownTime & tm )
78{
79 m_year = tm.year() ;
80 m_month = tm.month() ;
81 m_day = tm.day() ;
82}
83
84std::string G::Date::str( Format format ) const
85{
86 std::ostringstream ss ;
87 if( format == Format::yyyy_mm_dd_slash )
88 {
89 ss << yyyy() << "/" << mm() << "/" << dd() ;
90 }
91 else if( format == Format::yyyy_mm_dd )
92 {
93 ss << yyyy() << mm() << dd() ;
94 }
95 else if( format == Format::mm_dd )
96 {
97 ss << mm() << dd() ;
98 }
99 else
100 {
101 G_ASSERT( !"enum error" ) ;
102 }
103 return ss.str() ;
104}
105
106 int G::Date::monthday() const
107{
108 return m_day ;
109}
110
111std::string G::Date::dd() const
112{
113 std::ostringstream ss ;
114 ss << std::setw(2) << std::setfill('0') << m_day ;
115 return ss.str() ;
116}
117
118std::string G::Date::mm() const
119{
120 std::ostringstream ss ;
121 ss << std::setw(2) << std::setfill('0') << m_month ;
122 return ss.str() ;
123}
124
125G::Date::Weekday G::Date::weekday() const
126{
127 if( ! m_weekday_set )
128 {
129 BrokenDownTime bdt = BrokenDownTime::midday( m_year , m_month , m_day ) ;
130 const_cast<Date*>(this)->m_weekday_set = true ;
131 const_cast<Date*>(this)->m_weekday = Weekday(bdt.wday()) ;
132 }
133 return m_weekday ;
134}
135
136std::string G::Date::weekdayName( bool brief ) const
137{
138 if( weekday() == Weekday::sunday ) return brief ? "Sun" : "Sunday" ;
139 if( weekday() == Weekday::monday ) return brief ? "Mon" : "Monday" ;
140 if( weekday() == Weekday::tuesday ) return brief ? "Tue" : "Tuesday" ;
141 if( weekday() == Weekday::wednesday ) return brief ? "Wed" : "Wednesday" ;
142 if( weekday() == Weekday::thursday ) return brief ? "Thu" : "Thursday" ;
143 if( weekday() == Weekday::friday ) return brief ? "Fri" : "Friday" ;
144 if( weekday() == Weekday::saturday ) return brief ? "Sat" : "Saturday" ;
145 return "" ;
146}
147
148G::Date::Month G::Date::month() const
149{
150 return Month(m_month) ;
151}
152
153std::string G::Date::monthName( bool brief ) const
154{
155 if( month() == Month::january ) return brief ? "Jan" : "January" ;
156 if( month() == Month::february ) return brief ? "Feb" : "February" ;
157 if( month() == Month::march ) return brief ? "Mar" : "March" ;
158 if( month() == Month::april ) return brief ? "Apr" : "April" ;
159 if( month() == Month::may ) return "May" ;
160 if( month() == Month::june ) return brief ? "Jun" : "June" ;
161 if( month() == Month::july ) return brief ? "Jul" : "July" ;
162 if( month() == Month::august ) return brief ? "Aug" : "August" ;
163 if( month() == Month::september ) return brief ? "Sep" : "September" ;
164 if( month() == Month::october ) return brief ? "Oct" : "October" ;
165 if( month() == Month::november ) return brief ? "Nov" : "November" ;
166 if( month() == Month::december ) return brief ? "Dec" : "December" ;
167 return "" ;
168}
169
170 int G::Date::year() const
171{
172 return m_year ;
173}
174
175std::string G::Date::yyyy() const
176{
177 std::ostringstream ss ;
178 ss << std::setw(4) << std::setfill('0') << m_year ;
179 return ss.str() ;
180}
181
182 G::Date & G::Date::operator++()
183{
184 ++m_day ;
185 if( m_day == (lastDay(m_month,m_year)+1) )
186 {
187 m_day = 1 ;
188 ++m_month ;
189 if( m_month == 13 )
190 {
191 m_month = 1 ;
192 ++m_year ;
193 }
194 }
195 if( m_weekday_set )
196 {
197 if( m_weekday == Weekday::saturday )
198 m_weekday = Weekday::sunday ;
199 else
200 m_weekday = static_cast<Weekday>(static_cast<int>(m_weekday)+1) ;
201 }
202 return *this ;
203}
204
205 G::Date & G::Date::operator--()
206{
207 if( m_day == 1 )
208 {
209 if( m_month == 1 )
210 {
211 m_year-- ;
212 m_month = 12 ;
213 }
214 else
215 {
216 m_month-- ;
217 }
218
219 m_day = lastDay( m_month , m_year ) ;
220 }
221 else
222 {
223 m_day-- ;
224 }
225 if( m_weekday_set )
226 {
227 if( m_weekday == Weekday::sunday )
228 m_weekday = Weekday::saturday ;
229 else
230 m_weekday = static_cast<Weekday>(static_cast<int>(m_weekday)-1) ;
231 }
232 return *this ;
233}
234
235 int G::Date::lastDay( int month , int year )
236{
237 int end = 30 ;
238 if( month == 1 ||
239 month == 3 ||
240 month == 5 ||
241 month == 7 ||
242 month == 8 ||
243 month == 10 ||
244 month == 12 )
245 {
246 end = 31 ;
247 }
248 else if( month == 2 )
249 {
250 end = isLeapYear(year) ? 29 : 28 ;
251 }
252 return end ;
253}
254
255 bool G::Date::isLeapYear( int y )
256{
257 return y >= 1800 && ( y % 400 == 0 || ( y % 100 != 0 && y % 4 == 0 ) ) ;
258}
259
260 bool G::Date::operator==( const Date &other ) const
261{
262 return
263 year() == other.year() &&
264 month() == other.month() &&
265 monthday() == other.monthday() ;
266}
267
268 bool G::Date::operator!=( const Date &other ) const
269{
270 return !( other == *this ) ;
271}
272
G::BrokenDownTime
An encapsulation of 'struct std::tm'.
Definition: gdatetime.h:45
G::BrokenDownTime::wday
int wday() const
Returns week day where sunday=0 and saturday=6.
Definition: gdatetime.cpp:232
G::BrokenDownTime::day
int day() const
Returns the 1..31 month-day value.
Definition: gdatetime.cpp:227
G::BrokenDownTime::midday
static BrokenDownTime midday(int year, int month, int day)
Factory function for midday on the given date.
Definition: gdatetime.cpp:168
G::BrokenDownTime::month
int month() const
Returns the 1..12 month value.
Definition: gdatetime.cpp:222
G::BrokenDownTime::year
int year() const
Returns the four-digit year value.
Definition: gdatetime.cpp:217
G::Date::LocalTime
An overload discriminator class for Date constructors.
Definition: gdate.h:43
G::Date
A day-month-year date class.
Definition: gdate.h:40
G::Date::Date
Date()
Default constructor for the current date in the UTC timezone.
Definition: gdate.cpp:39
G::Date::operator--
Date & operator--()
Decrements the date by one day.
Definition: gdate.cpp:205
G::Date::monthName
std::string monthName(bool brief=false) const
Returns the month as a string (in english).
Definition: gdate.cpp:153
G::Date::weekdayName
std::string weekdayName(bool brief=false) const
Returns an english string representation of the day of the week.
Definition: gdate.cpp:136
G::Date::operator==
bool operator==(const Date &rhs) const
Comparison operator.
Definition: gdate.cpp:260
G::Date::month
Month month() const
Returns the month.
Definition: gdate.cpp:148
G::Date::yearUpperLimit
static int yearUpperLimit()
Returns the largest supported year value.
Definition: gdate.cpp:29
G::Date::monthday
int monthday() const
Returns the day of the month.
Definition: gdate.cpp:106
G::Date::operator++
Date & operator++()
Increments the date by one day.
Definition: gdate.cpp:182
G::Date::yyyy
std::string yyyy() const
Returns the year as a four-digit decimal string.
Definition: gdate.cpp:175
G::Date::dd
std::string dd() const
Returns the day of the month as a two-digit decimal string.
Definition: gdate.cpp:111
G::Date::str
std::string str(Format format=Format::yyyy_mm_dd_slash) const
Returns a string representation of the date.
Definition: gdate.cpp:84
G::Date::weekday
Weekday weekday() const
Returns the day of the week.
Definition: gdate.cpp:125
G::Date::operator!=
bool operator!=(const Date &rhs) const
Comparison operator.
Definition: gdate.cpp:268
G::Date::yearLowerLimit
static int yearLowerLimit()
Returns the smallest supported year value.
Definition: gdate.cpp:34
G::Date::year
int year() const
Returns the year.
Definition: gdate.cpp:170
G::Date::mm
std::string mm() const
Returns the month as a two-digit decimal string.
Definition: gdate.cpp:118
G::SystemTime
Represents a unix-epoch time with microsecond resolution.
Definition: gdatetime.h:125
G::SystemTime::now
static SystemTime now()
Factory function for the current time.
Definition: gdatetime.cpp:260
G::SystemTime::local
BrokenDownTime local() const
Returns the locale-dependent local broken-down time.
Definition: gdatetime.cpp:286
G::SystemTime::utc
BrokenDownTime utc() const
Returns the utc broken-down time.
Definition: gdatetime.cpp:291
G::format
A simple version of boost::format for formatting strings in an i18n-friendly way.
Definition: gformat.h:46
gassert.h
gdate.h
glog.h