cDuration
Overview / Purpose
The cDuration module provides the cDuration struct and functions to manipulate and interprete it. A cDuration value represents a duration of time measured in nanoseconds. A cDuration can be positive or negative, for both cases is the maximum value 15250w 1d 23h 47m 16.854775807s, thats approximately 290 years. Every higher/lower value will be a null cDuration value that is invalid.
Types and Definitions
cDuration
struct cDuration { int64_t _v; }; typedef struct cDuration cDuration;
The cDuration struct has just the attribute _v that safes the internal value. It should not be accessd directly.
Generated
cDurationSlice
struct cDurationSlice { int64_t s; cDuration const* v; }; typedef struct cDurationSlice cDurationSlice;
Via the macros SLICE_DEF_C_ and SLICE_IMPL_C_ declared and implemented struct. The macros declare and implement also the following functions.
/* init */ cDurationSlice duration_slice_c( int64_t s, cDuration const* v ); cDurationSlice make_duration_slice_c( cDuration const* beg, cDuration const* end ); cDurationSlice emtpy_duration_slice_c( void ); /* sub */ cDurationSlice left_duration_slice_c( cDurationSlice slice, int64_t maxLen ); cDurationSlice mid_duration_slice_c( cDurationSlice slice, int64_t index ); cDurationSlice right_duration_slice_c( cDurationSlice slice, int64_t maxLen ); cDurationSlice sub_duration_slice_c( cDurationSlice slice, int64_t begIdx, int64_t endIdx);
cVarDurationSlice
struct cVarDurationSlice { int64_t s; cDuration* v; }; typedef struct cVarDurationSlice cVarDurationSlice;
Via the macros SLICE_DEF_C_ and SLICE_IMPL_C_ declared and implemented struct. The macros declare and implement also the following functions.
/* init */ cVarDurationSlice var_duration_slice_c( int64_t s, cDuration* v ); cVarDurationSlice make_var_duration_slice_c( cDuration* beg, cDuration* end ); cVarDurationSlice empty_var_duration_slice_c( void ); /* sub */ cVarDurationSlice left_var_duration_slice_c( cVarDurationSlice slice, int64_t maxLen ); cVarDurationSlice mid_var_duration_slice_c( cVarDurationSlice slice, int64_t index ); cVarDurationSlice right_var_duration_slice_c( cVarDurationSlice slice, int64_t maxLen ); cVarDurationSlice sub_var_duration_slice_c( cVarDurationSlice slice, int64_t begIdx, int64_t endIdx); /* var slice */ cVarDurationSlice as_var_duration_slice_c( cVarDurationSlice slice ); cVarDurationSlice cast_var_duration_slice_c( cVarDurationSlice slice, cDurationSlice sub ); int64_t set_duration_slice_c( cVarDurationSlice dst, cDurationSlice src );
Definitions
C_Week
int64_t const C_Week = 7L*24L*60L*60L*1000L*1000L*1000L;
Defines the multiplication factor to convert a week count to a duration value.
C_Day
int64_t const C_Day = 24L*60l*60L*1000L*1000L*1000L;
Defines the multiplication factor to convert a day count to a duration value.
C_Hour
int64_t const C_Hour = 60L*60L*1000L*1000L*1000L;
Defines the multiplication factor to convert a hour count to a duration value.
C_Min
int64_t const C_Min = 60L*1000L*1000L*1000L;
Defines the multiplication factor to convert a minute count to a duration value.
C_Sec
int64_t const C_Sec = 1000L*1000L*1000L;
Defines the multiplication factor to convert a second count to a duration value.
C_Msec
int64_t const C_Msec = 1000L*1000L;
Defines the multiplication factor to convert a millisecond count to a duration value.
C_Usec
int64_t const C_Usec = 1000L;
Defines the multiplication factor to convert a microsecond count to a duration value.
C_Nsec
int64_t const C_Nsec = 1L;
Defines the multiplication factor to convert a nanosecond count to a duration value.
Functions
init
Init functions
#include "clingo/lang/expect.h" #include "clingo/time/cDuration.h" TEMP_SLICE_DEF_C_( test, { cDuration dur; int64_t exp; } ) #define t_( ... ) ((test){__VA_ARGS__}) int main( void ) { init_tap_c_(); testSlice tests = slice_c_( test, t_( secs_c( 4851 ), 1*C_Hour + 20*C_Min + 51*C_Sec ), t_( mins_c( 132 ), 2*C_Hour + 12*C_Min ), t_( usecs_c( 40851123456L ), 11*C_Hour + 20*C_Min + 51*C_Sec + 123456*C_Usec ) ); for_each_c_( test const*, t, tests ) { bool res = ( t->dur._v == t->exp ); tap_descf_c( res, "test: %"PRIi64, index_of_c_( tests, t ) ); } return finish_tap_c_(); }
duration_c
cDuration duration_c( int64_t h, int64_t m, int64_t s, int64_t n );
Initialise a duration with hour, minute, second and nanosecond.
weeks_c
cDuration weeks_c( int64_t weeks );
Creates a duration from a week count.
days_c
cDuration days_c( int64_t days );
Creates a duration from a day count.
hours_c
cDuration hours_c( int64_t hours );
Creates a duration from a hour count.
mins_c
cDuration mins_c( int64_t minutes );
Creates a duration from a minute count.
secs_c
cDuration secs_c( int64_t seconds );
Creates a duration from a second count.
msecs_c
cDuration msecs_c( int64_t milliseconds );
Creates a duration from a millisecond count.
usecs_c
cDuration usecs_c( int64_t microseconds );
Creates a duration from a microsecond count.
nsecs_c
cDuration nsecs_c( int64_t nanoseconds );
Creates a duration from a nanosecond count.
null_duration_c
cDuration null_duration_c( void );
Returns a null duration, null durations are invalid.
from
duration_from_hmsn_c
cDuration duration_from_hmsn_c( cHmsn hmsn );
Create a cDuration value from a cHmsn value. An invalid cHmsn value leads to an invalid cDuration value.
hmsn_from_duration_c
cHmsn hmsn_from_duration_c( cDuration dur );
Creates a cHmsn value from a cDuration value. An invalid cDuration value leads to an invalid cHmsn value.
#include "clingo/lang/expect.h" #include "clingo/time/cDuration.h" TEMP_SLICE_DEF_C_( test, { cDuration dur; cHmsn exp; } ) #define t_( ... ) ((test){__VA_ARGS__}) int main( void ) { init_tap_c_(); testSlice tests = slice_c_( test, t_( nsecs_c( 1*C_Hour + 12*C_Min + 53*C_Sec + 654321*C_Usec ), hmsn_c( 1, 12, 53, 654321000 ) ), t_( nsecs_c( 34*C_Min + 47*C_Sec ), hms_c( 0, 34, 47 ) ), t_( nsecs_c( -2*C_Hour - 34*C_Min - 56*C_Sec - 987654321*C_Nsec ), hmsn_c( -2, -34, -56, -987654321 ) ) ); for_each_c_( test const*, t, tests ) { cHmsn x = hmsn_from_duration_c( t->dur ); bool res = eq_c( cmp_hmsn_c( x, t->exp ) ); tap_descf_c( res, "%d:%d:%d.%d", x.hour, x.min, x.sec, x.nsec ); } return finish_tap_c_(); }
conv
#include "clingo/lang/expect.h" #include "clingo/time/cDuration.h" int main( void ) { init_tap_c_(); // 32 mins == 1920 secs cDuration shortDur = duration_c( 0, 32, 15, 123456789 ); expect_c_( as_mins_c( shortDur ) == 32 ); expect_c_( as_secs_c( shortDur ) == 1935 ); expect_c_( as_msecs_c( shortDur ) == 1935123L ); expect_c_( as_usecs_c( shortDur ) == 1935123456L ); expect_c_( as_nsecs_c( shortDur ) == 1935123456789L ); return finish_tap_c_(); }
as_weeks_c
int64_t as_weeks_c( cDuration duration );
Returns the duration as integer week count.
as_days_c
int64_t as_days_c( cDuration duration );
Returns the duration as an integer day count.
as_hours_c
int64_t as_hours_c( cDuration duration );
Returns the duration as an integer hour count.
as_mins_c
int64_t as_mins_c( cDuration duration );
Returns the duration as an integer minute count.
as_secs_c
int64_t as_secs_c( cDuration duration );
Returns the duration as an integer second count.
as_msecs_c
int64_t as_msecs_c( cDuration duration );
Returns the duration as an integer millisecond count.
as_usecs_c
int64_t as_usecs_c( cDuration duration );
Returns the duration as an integer microsecond count.
as_nsecs_c
int64_t as_nsecs_c( cDuration duration );
Returns the duration as an integer nanosecond count.
to_time_unit_c
int64_t to_time_unit_c( int64_t val, int64_t from, int64_t to );
Converts a duration value from one multiplication factor to another.
#include "clingo/lang/expect.h" #include "clingo/time/cDuration.h" int main( void ) { init_tap_c_(); expect_c_( to_time_unit_c( 3, C_Min, C_Sec ) == 180 ); expect_c_( to_time_unit_c( 62, C_Min, C_Hour ) == 1 ); return finish_tap_c_(); }
overall
add_duration_c
cDuration add_duration_c( cDuration a, cDuration b );
Adds both duration value to one single value.
#include "clingo/lang/expect.h" #include "clingo/time/cDuration.h" TEMP_SLICE_DEF_C_( test, { cDuration a; cDuration b; cDuration exp; char const* desc; } ) #define t_( ... ) ((test){__VA_ARGS__}) int main( void ) { init_tap_c_(); testSlice tests = slice_c_( test, // days t_( duration_c( 22*24, 14, 3, 0 ), days_c( 2 ), duration_c( 24*24, 14, 3, 0 ), "add 2d" ), t_( duration_c( 22*24, 14, 3, 0 ), days_c( -20 ), duration_c( 2*24, 14, 3, 0 ), "add -20d" ), // hours t_( duration_c( 126, 4, 24, 0 ), hours_c( 1 ), duration_c( 127, 4, 24, 0 ), "add 1h" ), t_( duration_c( 126, 4, 24, 0 ), hours_c( -5 ), duration_c( 121, 4, 24, 0 ), "add -5h" ), t_( duration_c( 0, 4, 24, 0 ), hours_c( -10 ), duration_c( -9, -55, -36, 0 ), "add -10h" ), // mins t_( duration_c( 13, 5, 14, 0 ), mins_c( 50 ), duration_c( 13, 55, 14, 0 ), "add 50m" ), t_( duration_c( 13, 5, 14, 0 ), mins_c( -6 ), duration_c( 12, 59, 14, 0 ), "add -6m" ), t_( duration_c( 1, 5, 14, 0 ), mins_c( -120 ), duration_c( 0, -54, -46, 0 ), "add -120m" ), // secs t_( duration_c( 1, 4, 24, 0 ), secs_c( 3 ), duration_c( 1, 4, 27, 0 ), "add 3s" ), t_( duration_c( 1, 0, 24, 0 ), secs_c( -30 ), duration_c( 0, 59, 54, 0 ), "add -30s" ) ); for_each_c_( test const*, t, tests ) { cDuration dur = add_duration_c( t->a, t->b ); tap_desc_c( eq_duration_c( dur, t->exp ), t->desc ); } return finish_tap_c_(); }
between_durations_c
cDuration between_durations_c( cDuration a, cDuration b );
Returns the duration between two duration values.
cmp_duration_c
int cmp_duration_c( cDuration a, cDuration b );
Compares two duration and returns the three possible results:
- <0
-
if a is shorter as b
- 0
-
if both dates are equal
- >0
-
if a is longer as b
duration_is_valid_c
bool duration_is_valid_c( cDuration dur );
Returns true if the duration is valid, otherwise false.
eq_duration_c
bool eq_duration_c( cDuration a, cDuration b );
Returns true if both durations are equal, otherwise false.
invert_duration_c
cDuration invert_duration_c( cDuration dur );
Inverts the duration value, from positive to negative or vice versa.
truncate_duration_c
#define truncate_duration_c_( Dur, Fac ) \ trauncate_duration_c( (Dur), (Fac), ref_c_( cDuration, null_duration_c() ) ) cDuration truncate_duration_c( cDuration dur, int64_t fac, cDuration tail[static 1] );
Returns the result of rounding dur toward zero to a multiple of fac, the truncated part of the duration can be stored in tail. If fac ⇐ 0, returns the function dur unchanged.
#include "clingo/lang/expect.h" #include "clingo/time/cDuration.h" TEMP_SLICE_DEF_C_( test, { cDuration dur; int64_t fac; cDuration exp; cDuration expTail; } ) #define t_( ... ) ((test){__VA_ARGS__}) int main( void ) { init_tap_c_(); cDuration dur = duration_c( 1, 15, 30, 918273645 ); testSlice tests = slice_c_( test, t_( dur, C_Nsec, dur, nsecs_c( 0 ) ), t_( dur, C_Usec, duration_c( 1, 15, 30, 918273000 ), nsecs_c( 645 ) ), t_( dur, C_Msec, duration_c( 1, 15, 30, 918000000 ), nsecs_c( 273645 ) ), t_( dur, C_Sec, duration_c( 1, 15, 30, 0 ), nsecs_c( 918273645 ) ), t_( dur, 2*C_Sec, duration_c( 1, 15, 30, 0 ), nsecs_c( 918273645 ) ), t_( dur, C_Min, duration_c( 1, 15, 0, 0 ), duration_c( 0, 0, 30, 918273645 ) ), t_( dur, 10*C_Min, duration_c( 1, 10, 0, 0 ), duration_c( 0, 5, 30, 918273645 ) ), t_( dur, C_Hour, duration_c( 1, 0, 0, 0 ), duration_c( 0, 15, 30, 918273645 ) ) ); for_each_c_( test const*, t, tests ) { cDuration tail; cDuration dur = truncate_duration_c( t->dur, t->fac, &tail ); bool res = eq_duration_c( dur, t->exp ) and eq_duration_c( tail, t->expTail ); tap_descf_c( res, "" ); } return finish_tap_c_(); }
io
The functions read_duration_c and write_duration_c are using the following format:
w/W |
Optional week value with a w or W after the value |
5w or 5W |
ww/WW |
Week value with a w or W after the value |
5w or 0W |
d/D |
Optional week value with a d or D after the value |
6d or 6D |
dd/DD |
Week value with a d or D after the value |
0d or 7D |
h/H |
Optional week value with a h or H after the value |
12h or 12H |
hh/HH |
Week value with a h or H after the value |
12h or 0H |
m/M |
Optional minute value with a m or M after the value |
|
mm/MM |
Minute value with a m or M after the value |
|
s/S |
Optional second value with a s or S after the value |
|
ss/SS |
Second value with a s or S after the value |
|
i/I |
Optional millisecond value with ms or MS after the value |
|
ii/II |
Millisecond value with ms or MS after the value |
|
u/U |
Optional microsecond value with µs or µS after the value |
|
uu/UU |
Microsecond value with µs or µS after the value |
|
n/N |
Optional nanosecond value with ns or NS after the value |
|
nn/NN |
Nanosecond value with ns or NS after the value |
|
*U |
Determines, based on the value, the right format SS.N, II.N, UU.N or NN |
|
*l |
Determines, based on the value, the right format ss.n, ii.n, uu.n or nn |
|
(space) |
Will insert a space to the output |
read_duration_c
#define read_duration_c( Sca, Dur ) \ read_duration_c( (Sca), (Dur), "" ) bool read_duration_c( cScanner sca[static 1], cDuration dur[static 1], char const fmt[static 1] );
Reads a cDuration value from a text with a scanner. The
#include "clingo/io/read.h" #include "clingo/lang/expect.h" #include "clingo/time/cDuration.h" TEMP_SLICE_DEF_C_( test, { char const* str; char const* fmt; cDuration exp; } ) #define t_( ... ) ((test){__VA_ARGS__}) int main( void ) { init_tap_c_(); testSlice tests = slice_c_( test, t_( "3d3m3.456789ms", "", duration_c( 72, 3, 0, 3456789 ) ), t_( "3d3m0.3456789s", "", duration_c( 72, 3, 0, 345678900 ) ), t_( "0W3D0H3M0.3S", "WDHM*U", duration_c( 72, 3, 0, 300000000 ) ), t_( "0W 3D 0H 3M 0.3S", "WW DD HH MM *U", duration_c( 72, 3, 0, 300000000 ) ), t_( "72h3m3.5s", "hm", duration_c( 72, 3, 0, 0 ) ), t_( "3s", "", secs_c( 3 ) ) ); for_each_c_( test const*, t, tests ) { cScanner* sca = &cstr_scanner_c_( t->str ); cDuration dur; bool res = read_duration_c( sca, &dur, t->fmt ); res &= eq_c( cmp_duration_c( dur, t->exp ) ); cRecorder* rec = &recorder_c_( 32 ); write_duration_c_( rec, dur ); tap_descf_c( res, "%s -> %s", t->fmt, turn_into_cstr_c( rec ) ); } return finish_tap_c_(); }
write_duration_c
#define write_duration_c_( Rec, Dur ) \ write_duration_c( (Rec), (Dur), "" ) bool write_duration_c( cRecorder rec[static 1], cDuration dur, char const fmt[static 1] );
Writes a cDuration value into the reocorder. The function will use "wdhm*l" as default format.
#include "clingo/lang/expect.h" #include "clingo/time/cDuration.h" TEMP_SLICE_DEF_C_( test, { cDuration dur; char const* fmt; char const* exp; } ) #define t_( ... ) ((test){__VA_ARGS__}) int main( void ) { init_tap_c_(); cDuration dur = duration_c( 72, 3, 0, 3456789 ); cDuration max = C_MaxDuration; testSlice tests = slice_c_( test, t_( dur, "", "3d3m3.456789ms" ), t_( dur, "WWDDHHMMSS.I", "0W3D0H3M0.003S" ), t_( dur, "WW DD HH MM SS.I", "0W 3D 0H 3M 0.003S" ), t_( dur, "hmss.n", "72h3m0.003456789s" ), t_( dur, "ww", "0w" ), t_( dur, "w", "" ), t_( max, "wwddhhmmss.n", "15250w1d23h47m16.854775807s" ), t_( invert_duration_c( max ), "", "-15250w1d23h47m16.854775807s" ), t_( max, "w", "15250w" ), t_( max, "d", "106751d" ), t_( max, "h", "2562047h" ), t_( max, "m", "153722867m" ), t_( max, "s", "9223372036s" ), t_( max, "ss.i", "9223372036.854s" ), t_( max, "ss.u", "9223372036.854775s" ), t_( max, "ss.n", "9223372036.854775807s" ), t_( max, "*U", "9223372036.854775807S" ) ); for_each_c_( test const*, t, tests ) { cRecorder* rec = &recorder_c_( 64 ); bool res = write_duration_c( rec, t->dur, t->fmt ); res &= recorded_is_c( rec, t->exp ); tap_descf_c( res, "'%s' -> '%s'", t->fmt, turn_into_cstr_c( rec ) ); } return finish_tap_c_(); }