ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
dateandtime.cpp
1//! @cond NO_DOX
2
3#define ARG0 (*args)
4#define ARG1 (*(args+1))
5#define INT(box) (box).Unbox<integer >()
6#define FLT(box) (box).Unbox<double >()
7#define DT(box) (box).Unbox<DateTime >()
8#define DUR(box) (box).Unbox<DateTime::Duration>()
9#define FUNC( name,...) Box name( Scope& scope, \
10 ArgIterator args, \
11 ArgIterator end ) \
12 { (void) scope; (void) args; (void) end; __VA_ARGS__ }
13
14#if !ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS
15# define TOINT(arg) arg
16#else
17# define TOINT(arg) integer(arg)
18#endif
19
20namespace alib { namespace expressions { namespace plugins {
21
22
23namespace {
24
25//##################################################################################################
26// ### Reverse generation: convert program constants to expression strings
27//##################################################################################################
28DOX_MARKER([DOX_EXPR_FToLiteral_3])
29void FToLiteral_Duration( const Box& constantValue, AString& expressionString ) {
30 // Unbox the time span and convert to nanoseconds
31 auto value= constantValue.Unbox<DateTime::Duration>().InNanoseconds();
32
33 // Find the best matching magnitude
34 NString result;
35 if( value == 0 )
36 result= "Milliseconds";
37 else {
38 result= "Nanoseconds";
39
40 if( (value % 1000) == 0 ) {
41 value/= 1000;
42 result= "Microseconds";
43 if( (value % 1000) == 0 ) {
44 value/= 1000;
45 result= "Milliseconds";
46 if( (value % 1000) == 0 ) {
47 value/= 1000;
48 result= "Seconds";
49 if( (value % 60) == 0 ) {
50 value/= 60;
51 result= "Minutes";
52 if( (value % 60) == 0 ) {
53 value/= 60;
54 result= "Hours";
55 if( (value % 24) == 0 ) {
56 value/= 24;
57 result= "Days";
58 } } } } } } }
59
60 // wWite the function argument
61 expressionString << result << '(' << value << ')' ;
62}
63DOX_MARKER([DOX_EXPR_FToLiteral_3])
64
65void FToLiteral_DateTime( const Box& constantValue, AString& expressionString ) {
66 CalendarDateTime ct( constantValue.Unbox<DateTime>(), lang::Timezone::UTC );
67
68 expressionString << "UTCDateTime( " << ct.Year << ','
69 << ct.Month << ','
70 << ct.Day << ','
71 << ct.Hour << ','
72 << ct.Minute << ','
73 << ct.Second << ','
74 << ct.Millisecond << ')' ;
75}
76
77
78//##################################################################################################
79// ### DateTime
80//##################################################################################################
81FUNC( dateTime , auto qtyArgs= end-args;
82 return CalendarDateTime( int( INT(ARG0) ) , // year
83 ( qtyArgs> 1 ) ? int( INT(*(args+1)) ) : 1, // month
84 ( qtyArgs> 2 ) ? int( INT(*(args+2)) ) : 1, // day
85 ( qtyArgs> 3 ) ? int( INT(*(args+3)) ) : 0, // hour
86 ( qtyArgs> 4 ) ? int( INT(*(args+4)) ) : 0, // minute
87 ( qtyArgs> 5 ) ? int( INT(*(args+5)) ) : 0, // second
88 ( qtyArgs> 6 ) ? int( INT(*(args+6)) ) : 0 // millisecond
89 )
91 )
92
93FUNC( utcDateTime , auto qtyArgs= end-args;
94 return CalendarDateTime( int( INT(ARG0) ) , // year
95 ( qtyArgs> 1 ) ? int( INT(*(args+1)) ) : 1, // month
96 ( qtyArgs> 2 ) ? int( INT(*(args+2)) ) : 1, // day
97 ( qtyArgs> 3 ) ? int( INT(*(args+3)) ) : 0, // hour
98 ( qtyArgs> 4 ) ? int( INT(*(args+4)) ) : 0, // minute
99 ( qtyArgs> 5 ) ? int( INT(*(args+5)) ) : 0, // second
100 ( qtyArgs> 6 ) ? int( INT(*(args+6)) ) : 0 // millisecond
101 )
103 )
104
106 ct.Hour= ct.Minute= ct.Second= ct.Millisecond= 0;
107 return ct.Get(lang::Timezone::Local); )
108FUNC( utcToday , CalendarDateTime ct(DateTime(), lang::Timezone::UTC);
109 ct.Hour= ct.Minute= ct.Second= ct.Millisecond= 0;
110 return ct.Get(lang::Timezone::UTC); )
111FUNC( now , return DateTime(); )
112FUNC( age , return DT(ARG0).Age(); )
113FUNC( isOlderThan , return DT(ARG0).IsOlderThan( DUR(ARG1) ); )
114FUNC( year , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::Local).Year ); )
115FUNC( month , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::Local).Month ); )
116FUNC( day , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::Local).Day ); )
117FUNC( dayOfWeek , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::Local).DayOfWeek ); )
118FUNC( hour , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::Local).Hour ); )
119FUNC( minute , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::Local).Minute ); )
120FUNC( millisecond , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::Local).Millisecond); )
121FUNC( utcYear , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::UTC ).Year ); )
122FUNC( utcMonth , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::UTC ).Month ); )
123FUNC( utcDay , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::UTC ).Day ); )
124FUNC( utcDayOfWeek , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::UTC ).DayOfWeek ); )
125FUNC( utcHour , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::UTC ).Hour ); )
126FUNC( utcMinute , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::UTC ).Minute ); )
127FUNC( utcMillisecond , return TOINT(CalendarDateTime(DT(ARG0), lang::Timezone::UTC ).Millisecond); )
128
129
130//##################################################################################################
131// ### Duration
132//##################################################################################################
133
134
135// constructor functions
136FUNC( nanosecondsInt , return DateTime::Duration::FromNanoseconds ( INT(ARG0) ); )
137
138FUNC( microsecondsInt , return DateTime::Duration::FromAbsoluteMicroseconds ( INT(ARG0) ); )
139FUNC( millisecondsInt , return DateTime::Duration::FromAbsoluteMilliseconds ( INT(ARG0) ); )
140FUNC( secondsInt , return DateTime::Duration::FromAbsoluteSeconds ( INT(ARG0) ); )
141FUNC( minutesInt , return DateTime::Duration::FromAbsoluteMinutes ( INT(ARG0) ); )
142FUNC( hoursInt , return DateTime::Duration::FromAbsoluteHours ( INT(ARG0) ); )
143FUNC( daysInt , return DateTime::Duration::FromAbsoluteDays ( INT(ARG0) ); )
144FUNC( weeksInt , return DateTime::Duration::FromAbsoluteDays ( INT(ARG0) * 7 ); )
145FUNC( monthsInt , return DateTime::Duration::FromAbsoluteDays ( INT(ARG0) * 30 ); )
146FUNC( yearsInt , return DateTime::Duration::FromAbsoluteDays ( INT(ARG0) * 365 ); )
147
148FUNC( microsecondsFlt , return DateTime::Duration::FromMicroseconds ( FLT(ARG0) ); )
149FUNC( millisecondsFlt , return DateTime::Duration::FromMilliseconds ( FLT(ARG0) ); )
150FUNC( secondsFlt , return DateTime::Duration::FromSeconds ( FLT(ARG0) ); )
151FUNC( minutesFlt , return DateTime::Duration::FromMinutes ( FLT(ARG0) ); )
152FUNC( hoursFlt , return DateTime::Duration::FromHours ( FLT(ARG0) ); )
153FUNC( daysFlt , return DateTime::Duration::FromDays ( FLT(ARG0) ); )
154FUNC( weeksFlt , return DateTime::Duration::FromDays ( FLT(ARG0) * 7.0 ); )
155FUNC( monthsFlt , return DateTime::Duration::FromDays ( FLT(ARG0) * 30.0 ); )
156FUNC( yearsFlt , return DateTime::Duration::FromDays ( FLT(ARG0) * 365.0 ); )
157
158
159// conversion
160FUNC( inDays , return DUR(ARG0).InDays (); )
161FUNC( inHours , return DUR(ARG0).InHours (); )
162FUNC( inMinutes , return DUR(ARG0).InMinutes (); )
163FUNC( inSeconds , return DUR(ARG0).InSeconds (); )
164FUNC( inMilliseconds , return DUR(ARG0).InMilliseconds(); )
165FUNC( inMicroseconds , return DUR(ARG0).InMicroseconds(); )
166FUNC( inNanoseconds , return DUR(ARG0).InNanoseconds (); )
167FUNC( inHertz , return DUR(ARG0).InHertz(2); )
168
169// binary operators time stamp
170FUNC( add_DTDUR , return DT(ARG0) + DUR(ARG1); )
171FUNC( add_DURDT , return DT(ARG1) + DUR(ARG0); )
172FUNC( sub_DTDUR , return DT(ARG0) - DUR(ARG1); )
173FUNC( sub_DTDT , return DT(ARG0) - DT(ARG1); )
174FUNC( eqDT , return DT(ARG0) == DT(ARG1); )
175FUNC( neqDT , return DT(ARG0) != DT(ARG1); )
176FUNC( gtDT , return DT(ARG0) > DT(ARG1); )
177FUNC( gteqDT , return DT(ARG0) >= DT(ARG1); )
178FUNC( smDT , return DT(ARG0) < DT(ARG1); )
179FUNC( smeqDT , return DT(ARG0) <= DT(ARG1); )
180
181
182// binary operators time span
183FUNC( add_DURDUR , return DUR(ARG0) + DUR(ARG1); )
184FUNC( sub_DURDUR , return DUR(ARG0) - DUR(ARG1); )
185FUNC( mul_DURF , return DUR(ARG0) * FLT(ARG1); )
186FUNC( mul_FDUR , return DUR(ARG1) * FLT(ARG0); )
187FUNC( mul_DURI , return DUR(ARG0) * int64_t( INT(ARG1) ); )
188FUNC( mul_IDUR , return DUR(ARG1) * int64_t( INT(ARG0) ); )
189FUNC( div_DURF , return DUR(ARG0) / FLT(ARG1); )
190FUNC( div_DURI , return DUR(ARG0) / int64_t( INT(ARG1) ); )
191
192FUNC( eqDUR , return DUR(ARG0) == DUR(ARG1); )
193FUNC( neqDUR , return DUR(ARG0) != DUR(ARG1); )
194FUNC( gtDUR , return DUR(ARG0) > DUR(ARG1); )
195FUNC( gteqDUR , return DUR(ARG0) >= DUR(ARG1); )
196FUNC( smDUR , return DUR(ARG0) < DUR(ARG1); )
197FUNC( smeqDUR , return DUR(ARG0) <= DUR(ARG1); )
198
199
200//##################################################################################################
201// ### Duration
202//##################################################################################################
203Calculus::OperatorTableEntry binaryOpTableDateTime[] =
204{
215
224
231};
232
233} // anonymous namespace
234
235
236//##################################################################################################
237// ### DateAndTime - Constructor. Creates the hash map
238//##################################################################################################
240DOX_MARKER([DOX_EXPR_FToLiteral_2])
241// register ToLiteral interface for class DateTime::Duration with boxing
243DOX_MARKER([DOX_EXPR_FToLiteral_2])
245}
246
248: Calculus( "ALib DateAndTime", compiler, CompilePriorities::DateAndTime ) {
249 // load identifier/function names from resources
250 constexpr int tableSize= 58;
251 Token functionNames[tableSize];
252 strings::util::LoadResourcedTokens( EXPRESSIONS, "CPD", functionNames
253 ALIB_DBG(,tableSize) );
254 Token* descriptor= functionNames;
255
256 // Constant identifiers
257 ConstantIdentifiers=
258 {
259 // January to december
260 { *descriptor++, TOINT(1) }, { *descriptor++, TOINT( 2) }, { *descriptor++, TOINT( 3) }, { *descriptor++, TOINT( 4) },
261 { *descriptor++, TOINT(5) }, { *descriptor++, TOINT( 6) }, { *descriptor++, TOINT( 7) }, { *descriptor++, TOINT( 8) },
262 { *descriptor++, TOINT(9) }, { *descriptor++, TOINT(10) }, { *descriptor++, TOINT(11) }, { *descriptor++, TOINT(12) },
263
264 // Sunday to saturday
265 { *descriptor++, TOINT(0) }, { *descriptor++, TOINT(1) }, { *descriptor++, TOINT(2) }, { *descriptor++, TOINT( 3) },
266 { *descriptor++, TOINT(4) }, { *descriptor++, TOINT(5) }, { *descriptor++, TOINT(6) },
267 };
268
269 // functions
270 Functions=
271 {
272DOX_MARKER([DOX_EXPR_FToLiteral_1])
273 { *descriptor++, CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(nanosecondsInt ), &Types::Duration , CTI },
274DOX_MARKER([DOX_EXPR_FToLiteral_1])
275 { *descriptor , CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(microsecondsInt ), &Types::Duration , CTI },
276 { *descriptor++, CALCULUS_SIGNATURE(Signatures::F ), CALCULUS_CALLBACK(microsecondsFlt ), &Types::Duration , CTI },
277 { *descriptor , CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(millisecondsInt ), &Types::Duration , CTI },
278 { *descriptor++, CALCULUS_SIGNATURE(Signatures::F ), CALCULUS_CALLBACK(millisecondsFlt ), &Types::Duration , CTI },
279 { *descriptor , CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(secondsInt ), &Types::Duration , CTI },
280 { *descriptor++, CALCULUS_SIGNATURE(Signatures::F ), CALCULUS_CALLBACK(secondsFlt ), &Types::Duration , CTI },
281 { *descriptor , CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(minutesInt ), &Types::Duration , CTI },
282 { *descriptor++, CALCULUS_SIGNATURE(Signatures::F ), CALCULUS_CALLBACK(minutesFlt ), &Types::Duration , CTI },
283 { *descriptor , CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(hoursInt ), &Types::Duration , CTI },
284 { *descriptor++, CALCULUS_SIGNATURE(Signatures::F ), CALCULUS_CALLBACK(hoursFlt ), &Types::Duration , CTI },
285 { *descriptor , CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(daysInt ), &Types::Duration , CTI },
286 { *descriptor++, CALCULUS_SIGNATURE(Signatures::F ), CALCULUS_CALLBACK(daysFlt ), &Types::Duration , CTI },
287 { *descriptor , CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(weeksInt ), &Types::Duration , CTI },
288 { *descriptor++, CALCULUS_SIGNATURE(Signatures::F ), CALCULUS_CALLBACK(weeksFlt ), &Types::Duration , CTI },
289 { *descriptor , CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(monthsInt ), &Types::Duration , CTI },
290 { *descriptor++, CALCULUS_SIGNATURE(Signatures::F ), CALCULUS_CALLBACK(monthsFlt ), &Types::Duration , CTI },
291 { *descriptor , CALCULUS_SIGNATURE(Signatures::I ), CALCULUS_CALLBACK(yearsInt ), &Types::Duration , CTI },
292 { *descriptor++, CALCULUS_SIGNATURE(Signatures::F ), CALCULUS_CALLBACK(yearsFlt ), &Types::Duration , CTI },
293
294 { *descriptor++, CALCULUS_SIGNATURE(Signatures::Dur ), CALCULUS_CALLBACK(inDays ), &Types::Float , CTI },
295 { *descriptor++, CALCULUS_SIGNATURE(Signatures::Dur ), CALCULUS_CALLBACK(inHours ), &Types::Float , CTI },
296 { *descriptor++, CALCULUS_SIGNATURE(Signatures::Dur ), CALCULUS_CALLBACK(inMinutes ), &Types::Float , CTI },
297 { *descriptor++, CALCULUS_SIGNATURE(Signatures::Dur ), CALCULUS_CALLBACK(inSeconds ), &Types::Float , CTI },
298 { *descriptor++, CALCULUS_SIGNATURE(Signatures::Dur ), CALCULUS_CALLBACK(inMilliseconds ), &Types::Float , CTI },
299 { *descriptor++, CALCULUS_SIGNATURE(Signatures::Dur ), CALCULUS_CALLBACK(inMicroseconds ), &Types::Float , CTI },
300 { *descriptor++, CALCULUS_SIGNATURE(Signatures::Dur ), CALCULUS_CALLBACK(inNanoseconds ), &Types::Float , CTI },
301 { *descriptor++, CALCULUS_SIGNATURE(Signatures::Dur ), CALCULUS_CALLBACK(inHertz ), &Types::Float , CTI },
302 { *descriptor++, CALCULUS_SIGNATURE(Signatures::IVar), CALCULUS_CALLBACK(dateTime ), &Types::DateTime , CTI },
303 { *descriptor++, CALCULUS_SIGNATURE(Signatures::IVar), CALCULUS_CALLBACK(utcDateTime ), &Types::DateTime , CTI },
304 { *descriptor++, CALCULUS_SIGNATURE(nullptr ), CALCULUS_CALLBACK(now ), &Types::DateTime , ETI },
305 { *descriptor++, CALCULUS_SIGNATURE(nullptr ), CALCULUS_CALLBACK(today ), &Types::DateTime , ETI },
306 { *descriptor++, CALCULUS_SIGNATURE(nullptr ), CALCULUS_CALLBACK(utcToday ), &Types::DateTime , ETI },
307 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(age ), &Types::Duration , ETI },
308 { *descriptor++, CALCULUS_SIGNATURE(Signatures::DDur), CALCULUS_CALLBACK(isOlderThan ), &Types::Boolean , ETI },
309 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(year ), &Types::Integer , CTI },
310 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(month ), &Types::Integer , CTI },
311 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(day ), &Types::Integer , CTI },
312 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(dayOfWeek ), &Types::Integer , CTI },
313 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(hour ), &Types::Integer , CTI },
314 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(minute ), &Types::Integer , CTI },
315 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(millisecond ), &Types::Integer , CTI },
316 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(utcYear ), &Types::Integer , CTI },
317 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(utcMonth ), &Types::Integer , CTI },
318 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(utcDay ), &Types::Integer , CTI },
319 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(utcDayOfWeek ), &Types::Integer , CTI },
320 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(utcHour ), &Types::Integer , CTI },
321 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(utcMinute ), &Types::Integer , CTI },
322 { *descriptor++, CALCULUS_SIGNATURE(Signatures::D ), CALCULUS_CALLBACK(utcMillisecond ), &Types::Integer , CTI },
323 };
324
325 // binary operators
326 AddOperators( binaryOpTableDateTime );
327
328 ALIB_ASSERT_ERROR( descriptor - functionNames == tableSize, "EXPR",
329 "Descriptor table size mismatch: Consumed {} descriptors, {} available.",
330 descriptor - functionNames, tableSize )
331}
332
333
334}}} // namespace [alib::expressions::detail]
335
336#undef BOL
337#undef INT
338#undef FLT
339#undef FUNC
340#undef FUNC
341#undef UN_MAP_ENTRY
342#undef BIN_MAP_ENTRY
343#undef BIN_ALIAS_ENTRY
344
345
346//! @endcond
#define A_CHAR(STR)
#define ALIB_DBG(...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
int Hour
The calendar hour (0..23).
Definition calendar.hpp:58
DateTime Get(lang::Timezone timezone=lang::Timezone::Local) const
Definition calendar.cpp:87
#define CALCULUS_CALLBACK(func)
#define CALCULUS_SIGNATURE(BoxPointerArray)
void BootstrapRegister(typename TFDecl::Signature function)
Definition box.hpp:1166
@ Local
Denotes local time.
@ UTC
Denotes UTC (coordinated universal time).
Definition alox.cpp:14
strings::TString< nchar > NString
Type alias in namespace #"%alib".
Definition string.hpp:2174
boxing::Box Box
Type alias in namespace #"%alib".
Definition box.hpp:1128
expressions::Compiler Compiler
Type alias in namespace #"%alib".
Definition compiler.hpp:535
strings::util::CalendarDateTime CalendarDateTime
Type alias in namespace #"%alib".
Definition calendar.hpp:509
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
strings::util::Token Token
Type alias in namespace #"%alib".
Definition token.hpp:396
time::DateTime DateTime
Type alias in namespace #"%alib".
Definition datetime.hpp:188
static Box Integer
Sample type-box for integer types. (Precisely for type #"lang::integer".).
static Box Boolean
Sample type-box for C++ type bool.
static Box Float
Sample type-box for C++ type double.
static Box DateTime
Sample type-box for date and time values of type #"time::DateTime").
const std::tuple< String, Type, Type, CallbackDecl, Type, CTInvokable > OperatorTableEntry
Definition calculus.hpp:445
static constexpr CTInvokable CTI
Definition calculus.hpp:235