ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
calendar.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2024 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
8
9#if !defined(ALIB_DOX)
10# if !defined(HPP_ALIB_LANG_BASECAMP)
12# endif
13# if !defined (HPP_ALIB_LANG_BASECAMP)
15# endif
16# if !defined (HPP_ALIB_STRINGS_NUMBERFORMAT)
18# endif
19# if !defined (HPP_ALIB_STRINGS_FORMAT)
21# endif
22# if !defined (HPP_ALIB_STRINGS_SUBSTRING)
24# endif
25# if !defined(HPP_ALIB_TIME_TIME)
26# include "alib/time/time.hpp"
27# endif
28# if !defined (HPP_ALIB_LANG_RESOURCES_RESOURCES)
30# endif
31# if !defined (HPP_ALIB_CAMP_DIRECTORY)
33# endif
34# if !defined (HPP_ALIB_CAMP_CALENDAR)
36# endif
37# if !defined (HPP_ALIB_ENUMS_RECORDBOOTSTRAP)
39# endif
40# if !defined(HPP_ALIB_ENUMS_SERIALIZATION)
42# endif
43#if !defined(HPP_ALIB_LANG_FORMAT_FWDS)
45#endif
46#endif // !defined(ALIB_DOX)
47
48namespace alib::lang::system {
49
50// #################################################################################################
51// CalendarDateTime
52// #################################################################################################
54{
55 Year=
56 Month=
57 Day=
58 Hour=
59 Minute=
60 Second=
61 Millisecond= 0;
62 DayOfWeek= -1;
63}
64
65void CalendarDateTime::Set( const DateTime& timeStamp, lang::Timezone timezone )
66{
67 Clear();
68
69 #if defined( _WIN32 )
70 SYSTEMTIME st= timeStamp.ToSystemTime( timezone );
71
72 Year= st.wYear;
73 Day= st.wDay;
74 DayOfWeek= st.wDayOfWeek;
75 Month= st.wMonth;
76 Hour= st.wHour;
77 Minute= st.wMinute;
78 Second= st.wSecond;
79
80 #elif defined (__GLIBCXX__) || defined(__APPLE__) || defined(__ANDROID_NDK__)
81 struct tm tm;
82 time_t tt= timeStamp.InEpochSeconds();
83 if ( timezone == lang::Timezone::UTC )
84 {
85 tm.tm_isdst= 0; // daylight saving off
86 gmtime_r( &tt, &tm );
87 }
88 else
89 {
90 tm.tm_isdst= -1; // daylight saving auto
91 localtime_r( &tt, &tm );
92 }
93
94 Year= tm.tm_year + 1900;
95 Day= tm.tm_mday;
96 DayOfWeek= tm.tm_wday;
97 Month= tm.tm_mon + 1;
98 Second= tm.tm_sec;
99 Hour= tm.tm_hour;
100 Minute= tm.tm_min;
101
102 #else
103 #pragma message ("Unknown Platform in file: " __FILE__ )
104 #endif
105}
106
108{
110
111 #if defined( _WIN32 )
112
113 SYSTEMTIME st;
114 st.wYear= (WORD) Year;
115 st.wDay= (WORD) Day;
116 st.wDayOfWeek= (WORD) DayOfWeek;
117 st.wMonth= (WORD) Month;
118 st.wHour= (WORD) Hour;
119 st.wMinute= (WORD) Minute;
120 st.wSecond= (WORD) Second;
121 st.wMilliseconds= 0;
122
123 result= DateTime::FromSystemTime( st, timezone );
124
125 #elif defined (__GLIBCXX__) || defined(__APPLE__) || defined(__ANDROID_NDK__)
126 struct tm tm;
127 tm.tm_year= Year - 1900;
128 tm.tm_mday= Day;
129 tm.tm_mon= Month -1;
130 tm.tm_hour= Hour;
131 tm.tm_min= Minute;
132 tm.tm_sec= Second;
133
134 time_t tt;
135 if ( timezone == lang::Timezone::UTC )
136 {
137 tm.tm_isdst= 0; // daylight saving off
138 tt= timegm( &tm );
139 }
140 else
141 {
142 tm.tm_isdst= -1; // daylight saving auto
143 tt= mktime( &tm );
144 }
145
146 result= DateTime::FromEpochSeconds( tt );
147
148
149 #else
150 #pragma message ("Unknown Platform in file: " __FILE__ )
151 #endif
152
153 return result;
154}
155
156
157
158// #################################################################################################
159// CalendarDuration
160// #################################################################################################
162{
163 Days=
164 Hours=
165 Minutes=
166 Seconds=
169 Nanoseconds= 0;
170}
171#define NanosPerDay INT64_C( 86400000000000 ) ///< Constant denoting number of nanoseconds of a day.
172#define NanosPerHour INT64_C( 3600000000000 ) ///< Constant denoting number of nanoseconds of an hour.
173#define NanosPerMinute INT64_C( 60000000000 ) ///< Constant denoting number of nanoseconds of a minute.
174#define NanosPerSecond INT64_C( 1000000000 ) ///< Constant denoting number of nanoseconds of a second.
175#define NanosPerMillisecond INT64_C( 1000000 ) ///< Constant denoting number of nanoseconds of a millisecond.
176#define NanosPerMicrosecond INT64_C( 1000 ) ///< Constant denoting number of nanoseconds of a microsecond.
177
178
180{
181 Clear();
182 decltype(nanos) fract;
183 if ( nanos > NanosPerDay ) { Days= static_cast<int>( fract= nanos / NanosPerDay ); nanos-= fract * NanosPerDay; }
184 if ( nanos > NanosPerHour ) { Hours= static_cast<int>( fract= nanos / NanosPerHour ); nanos-= fract * NanosPerHour; }
185 if ( nanos > NanosPerMinute ) { Minutes= static_cast<int>( fract= nanos / NanosPerMinute ); nanos-= fract * NanosPerMinute; }
186 if ( nanos > NanosPerSecond ) { Seconds= static_cast<int>( fract= nanos / NanosPerSecond ); nanos-= fract * NanosPerSecond; }
187 if ( nanos > NanosPerMillisecond ) { Milliseconds= static_cast<int>( fract= nanos / NanosPerMillisecond ); nanos-= fract * NanosPerMillisecond; }
188 if ( nanos > NanosPerMicrosecond ) { Microseconds= static_cast<int>( fract= nanos / NanosPerMicrosecond ); }
189}
190
192{
193 return Days * NanosPerDay
194 + Hours * NanosPerHour
195 + Minutes * NanosPerMinute
196 + Seconds * NanosPerSecond
197 + Milliseconds * NanosPerMillisecond
198 + Microseconds * NanosPerMicrosecond
199 + Nanoseconds;
200}
201
202// #################################################################################################
203// CalendarDate
204// #################################################################################################
205void CalendarDate::Set( const DateTime& dateTime, lang::Timezone timezone )
206{
207 CalendarDateTime cdt(dateTime, timezone);
208 stamp= uint32_t( cdt.Year ) << 12
209 | uint32_t( cdt.Month ) << 8
210 | uint32_t( cdt.Day ) << 3
211 | uint32_t( cdt.DayOfWeek ) ;
212}
213void CalendarDate::Set( int year, int month, int day, int dayOfWeek )
214{
215 ALIB_ASSERT_ERROR( year >= 0 && year <= 1048575, "CAMP", "CalendarDate: Years must be between 0 and 1,048,575." )
216 ALIB_ASSERT_ERROR( month >= 1 && month <= 12 , "CAMP", "CalendarDate: Months must be between 1 and 12." )
217 ALIB_ASSERT_ERROR( day >= 1 && day <= 31 , "CAMP", "CalendarDate: Days must be between 1 and 31." )
218 ALIB_ASSERT_ERROR( dayOfWeek <= 6 , "CAMP", "CalendarDate: Day of week must be either negative or between 0 and 6." )
219
220 // get day of week, if not given
221 if( dayOfWeek< 0 )
222 {
223 dayOfWeek= CalendarDateTime( CalendarDateTime( year, month, day, 12, 0, 0 ).Get(),
225 }
226 #if ALIB_DEBUG
227 else
228 {
229 CalendarDateTime cdt( year, month, day, 12, 0, 0 );
230 cdt= CalendarDateTime( cdt.Get( )); // get day of week
231 ALIB_ASSERT_ERROR( dayOfWeek == cdt.DayOfWeek, "CAMP",
232 "Day of week does not correspond to given date. Should be: ", cdt.DayOfWeek )
233 }
234 #endif
235 stamp= uint32_t( year ) << 12
236 | uint32_t( month ) << 8
237 | uint32_t( day ) << 3
238 | uint32_t( dayOfWeek ) ;
239}
240
241DateTime CalendarDate::Get( lang::Timezone timezone, int hour, int minute, int second ) const
242{
243 return CalendarDateTime( Year(), Month(), Day(), hour, minute, second).Get( timezone );
244}
245
247{
248 // use the system for it
249 return CalendarDate( CalendarDateTime( Year(), Month(), Day(), 12 ).Get()
250 + DateTime::Duration::FromAbsoluteDays( daysToAdd ),
252}
253
255{
256 auto day = Day ();
257 auto month= Month();
258 auto year = Year ();
259
260 // can we do it manually?
261 if( ( month != 2 && day != 30 )
262 || ( month == 2 && day != 28 ) )
263 {
264 if( ( day != 31 )
265 && ( day != 29 || month != 2 ) )
266 {
267 day++;
268 }
269 else
270 {
271 day= 1;
272 if( ++month == 13 )
273 {
274 month= 1;
275 ++year;
276 }
277 }
278 Set( year, month, day, (DayOfWeek() + 1) % 7 );
279 return *this;
280 }
281
282 // use the system for it
283 CalendarDateTime cdt( year, month, day, 12 );
284 return *this= CalendarDate( cdt.Get() + DateTime::Duration::FromAbsoluteDays(1), lang::Timezone::UTC );
285}
286
288{
289 auto day = Day();
290
291 // can we do it manually?
292 if( day > 1 )
293 {
294 stamp= ( stamp & ~lang::LowerMask<8, uint32_t>() )
295 | ( uint32_t( day-1 ) << 3 )
296 | ( ( (stamp & 7) + 6 ) % 7 ) ; // +6 corresponds to -1 in modulo op
297 return *this;
298 }
299
300 // use the system for it
301 return *this= CalendarDate( Get() - DateTime::Duration::FromAbsoluteDays(1), lang::Timezone::UTC );
302}
303
304} // namespace [ alib::lang::system]
ALIB_API void Set(const DateTime &timeStamp, lang::Timezone timezone=lang::Timezone::Local)
Definition calendar.cpp:65
ALIB_API DateTime Get(lang::Timezone timezone=lang::Timezone::Local) const
Definition calendar.cpp:107
ALIB_API CalendarDate operator--()
Definition calendar.cpp:287
ALIB_API CalendarDate operator+(int daysToAdd) const
Definition calendar.cpp:246
ALIB_API DateTime Get(lang::Timezone timezone=lang::Timezone::Local, int hour=12, int minute=0, int second=0) const
Definition calendar.cpp:241
uint32_t stamp
Encoded date value.
Definition calendar.hpp:373
ALIB_API CalendarDate operator++()
Definition calendar.cpp:254
ALIB_API void Set(int year, int month, int day, int dayOfWeek=-1)
Definition calendar.cpp:213
ALIB_API void FromNanoSeconds(int64_t nanos)
Definition calendar.cpp:179
static DateTime FromEpochSeconds(time_t epochSeconds)
Definition datetime.hpp:72
time_t InEpochSeconds() const
Definition datetime.hpp:58
static ALIB_API DateTime FromSystemTime(const SYSTEMTIME &systemTime, lang::Timezone timezone=lang::Timezone::Local)
ALIB_API SYSTEMTIME ToSystemTime(lang::Timezone timezone=lang::Timezone::Local) const
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:984
@ UTC
Denotes UTC (coordinated universal time).
@ Get
Denotes to search data.
lang::system::CalendarDateTime CalendarDateTime
Type alias in namespace alib.
Definition calendar.hpp:753