cDate
Overview
Types and Definitions
cDate
struct cDate
{
int64_t _v;
};
typedef struct cDate cDate;
The cDate struct has just the attribute _v that represent the date value.
Functions
init
date_c
cDate date_c( int64_t year, int64_t month, int64_t day );
Initialise a date with year, month and day. If the specified date is invalid, the date is not set and date_is_valid_c returns false.
local_date_c
cDate local_date_c( void );
Returns the current local date, as reported by the system clock.
null_date_c
cDate null_date_c( void );
Returns a null date, null dates are invalid.
utc_date_c
cDate utc_date_c( void );
Returns the current UTC date, as reported by the system clock.
from
from_julian_day_c
cDate from_julian_day_c( int64_t jd );
Creates a date from the Julian day value jd.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
int64_t jd;
cYmd exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
// http://aa.usno.navy.mil/data/docs/JulianDate.php 12:00:00
testSlice tests = slice_c_( test,
t_( 1721424, ymd_c( 1, c_Jan, 1 ) ),
t_( 1842713, ymd_c( 333, c_Jan, 27 ) ),
t_( 2299160, ymd_c( 1582, c_Oct, 4 ) ),
t_( 2299161, ymd_c( 1582, c_Oct, 15 ) ),
t_( 2415021, ymd_c( 1900, c_Jan, 1 ) ),
t_( 2440588, ymd_c( 1970, c_Jan, 1 ) ),
t_( 2447893, ymd_c( 1990, c_Jan, 1 ) ),
t_( 2451545, ymd_c( 2000, c_Jan, 1 ) ),
t_( 2453750, ymd_c( 2006, c_Jan, 14 ) ),
t_( 2455281, ymd_c( 2010, c_Mar, 25 ) ),
t_( 2456798, ymd_c( 2014, c_May, 20 ) )
);
for_each_c_( test const*, t, tests )
{
cDate date = from_julian_day_c( t->jd );
bool res = eq_c( cmp_ymd_c( as_ymd_c( date ), t->exp ) );
//bool res = eq_date_c( date, t->exp );
tap_descf_c( res, "%"PRIi64, t->jd );
}
return finish_tap_c_();
}
from_ordinal_date_c
cDate from_ordinal_date_c( cOrdinalDate od );
Creates a date from the year and day value from the cOrdinalDate value.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cOrdinalDate od = ordinal_date_c( 1981, 95 );
cDate res = from_ordinal_date_c( od );
expect_c_( eq_date_c( res, date_c( 1981, c_Apr, 5 ) ) );
return finish_tap_c_();
}
from_week_date_c
cDate from_week_date_c( cWeekDate wd );
Creates a date from the year, week and day value from the cWeekDate value.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cWeekDate wd = week_date_c( 2008, 39, c_Fri );
cDate res = from_week_date_c( wd );
println_scope_c_( rec, 256 )
{
write_week_date_c_( rec, wd );
record_endl_c( rec );
write_date_c_( rec, res );
}
expect_c_( eq_date_c( res, date_c( 2008, c_Sep, 26 ) ) );
return finish_tap_c_();
}
from_ymd_c
cDate from_ymd_c( cYmd ymd );
Creates a date from the year, month and day values from the ymd instance.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate res = from_ymd_c( ymd_c( 2012, c_Apr, 8 ) );
expect_c_( eq_date_c( res, date_c( 2012, c_Apr, 8 ) ) );
return finish_tap_c_();
}
as
as_julian_day_c
int64_t as_julian_day_c( cDate date );
Returns the date as Julian day.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
int32_t year;
c_Month month;
int8_t day;
int64_t jd;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
// http://aa.usno.navy.mil/data/docs/JulianDate.php 12:00:00
testSlice tests = slice_c_( test,
t_( 1, c_Jan, 1, 1721424 ),
t_( 333, c_Jan, 27, 1842713 ),
t_( 1582, c_Oct, 4, 2299160 ),
t_( 1582, c_Oct, 15, 2299161 ),
t_( 1900, c_Jan, 1, 2415021 ),
t_( 1970, c_Jan, 1, 2440588 ),
t_( 1990, c_Jan, 1, 2447893 ),
t_( 2000, c_Jan, 1, 2451545 ),
t_( 2006, c_Jan, 14, 2453750 ),
t_( 2010, c_Mar, 25, 2455281 ),
t_( 2014, c_May, 20, 2456798 )
);
for_each_c_( test const*, t, tests )
{
cDate const date = date_c( t->year, t->month, t->day );
int64_t const jd = as_julian_day_c( date );
tap_descf_c( jd == t->jd, "%d.%d.%d", t->year, t->month, t->day );
}
return finish_tap_c_();
}
as_ordinal_date_c
cOrdinalDate as_ordinal_date_c( cDate date );
Returns the date as cOrdinalDate value.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate date = date_c( 1981, c_Apr, 5 );
cOrdinalDate res = as_ordinal_date_c( date );
expect_eq_c_( cmp_ordinal_date_c( res, ordinal_date_c( 1981, 95 ) ) );
return finish_tap_c_();
}
as_week_date_c
cWeekDate as_week_date_c( cDate date );
Returns the date as cWeekDate value.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate date = date_c( 2008, c_Sep, 26 );
cWeekDate res = as_week_date_c( date );
expect_eq_c_( cmp_week_date_c( res, week_date_c( 2008, 39, c_Fri ) ) );
return finish_tap_c_();
}
as_ymd_c
cYmd as_ymd_c( cDate date );
Returns the date as cYmd value.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate date;
cYmd res;
date = date_c( 2011, c_Apr, 24 );
res = as_ymd_c( date );
expect_eq_c_( cmp_ymd_c( res, ymd_c( 2011, c_Apr, 24 ) ) );
date = date_c( 2000, c_Jan, 1 );
res = as_ymd_c( date );
expect_eq_c_( cmp_ymd_c( res, ymd_c( 2000, c_Jan, 1 ) ) );
return finish_tap_c_();
}
prop
date_is_valid_c
bool date_is_valid_c( cDate date );
Returns true if the specified date (year, month, and day) is valid, otherwise false.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
expect_c_( !date_is_valid_c( date_c( 2011, c_Feb, 30 ) ) );
expect_c_( !date_is_valid_c( date_c( 2012, 13, 8 ) ) );
expect_c_( date_is_valid_c( date_c( 2012, c_Apr, 8 ) ) );
expect_c_( !date_is_valid_c( null_date_c() ) );
return finish_tap_c_();
}
date_day_of_year_c
int64_t date_day_of_year_c( cDate date );
Returns the day of the year (1 to 365 or 366 on leap years) of date.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
expect_c_( date_day_of_year_c( date_c( 2012, c_Jan, 1 ) ) == 1 );
expect_c_( date_day_of_year_c( date_c( 2012, c_May, 3 ) ) == 124 );
expect_c_( date_day_of_year_c( date_c( 2012, c_Dec, 31 ) ) == 366 );
return finish_tap_c_();
}
date_weekday_c
c_Weekday date_weekday_c( cDate date ;
Returns the weekday of date.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
expect_c_( date_weekday_c( date_c( 2012, c_Apr, 8 ) ) == c_Sun );
expect_c_( date_weekday_c( date_c( 1949, c_May, 23 ) ) == c_Mon );
expect_c_( date_weekday_c( date_c( 1789, c_Jul, 14 ) ) == c_Tue );
expect_c_( date_weekday_c( date_c( 1892, c_Jan, 18 ) ) == c_Mon );
expect_c_( date_weekday_c( date_c( 1989, c_Nov, 9 ) ) == c_Thu );
return finish_tap_c_();
}
next_weekday_date_c
cDate next_weekday_date_c( cDate date, c_Weekday wd );
Returns the next date that has the weekday wd.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
cDate base;
c_Weekday wd;
cDate exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
cDate date = date_c( 2014, c_Mar, 22 );
testSlice tests = slice_c_( test,
t_( date, c_Sun, date_c( 2014, c_Mar, 23 ) ),
t_( date, c_Wed, date_c( 2014, c_Mar, 26 ) ),
t_( date, c_Sat, date_c( 2014, c_Mar, 29 ) )
);
for_each_c_( test const*, t, tests )
{
cDate date = next_weekday_date_c( t->base, t->wd );
bool res = eq_date_c( date, t->exp );
cRecorder* rec = &recorder_c_( 16 );
write_date_c_( rec, date );
tap_desc_c( res, turn_into_cstr_c( rec ) );
}
return finish_tap_c_();
}
prev_weekday_date_c
cDate prev_weekday_date_c( cDate date, c_Weekday wd );
Returns the previous date that has the weekday wd.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
cDate base;
c_Weekday wd;
cDate exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
cDate date = date_c( 2014, c_Mar, 22 );
testSlice tests = slice_c_( test,
t_( date, c_Sat, date_c( 2014, c_Mar, 15 ) ),
t_( date, c_Mon, date_c( 2014, c_Mar, 17 ) ),
t_( date, c_Fri, date_c( 2014, c_Mar, 21 ) )
);
for_each_c_( test const*, t, tests )
{
cDate date = prev_weekday_date_c( t->base, t->wd );
bool res = eq_date_c( date, t->exp );
cRecorder* rec = &recorder_c_( 16 );
write_date_c_( rec, date );
tap_desc_c( res, turn_into_cstr_c( rec ) );
}
return finish_tap_c_();
}
add
add_days_to_date_c
cDate add_days_to_date_c( cDate date, int64_t days );
Returns a cDate date containing a date days later than the date (or earlier if days is negative). Returns an invalid cDate instance if the date is invalid or the new date is out of date.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate date = date_c( 2011, c_Mar, 31 );
cDate res = add_days_to_date_c( date, 20 );
expect_c_( eq_date_c( res, date_c( 2011, c_Apr, 20 ) ) );
res = add_days_to_date_c( date, -11 );
expect_c_( eq_date_c( res, date_c( 2011, c_Mar, 20 ) ) );
return finish_tap_c_();
}
add_weeks_to_date_c
cDate add_weeks_to_date_c( cDate date, int64_t weeks );
Returns a cDate instance containing a date weeks later than the date (or earlier if weeks is negative). If the ending day/month combination does not exist in the resulting month/year, this function will return a date that is the latest valid date.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate date = date_c( 2011, c_Mar, 31 );
cDate res = add_weeks_to_date_c( date, -3 );
expect_c_( eq_date_c( res, date_c( 2011, c_Mar, 10 ) ) );
res = add_weeks_to_date_c( date, 52 );
expect_c_( eq_date_c( res, date_c( 2012, c_Mar, 29 ) ) );
return finish_tap_c_();
}
add_months_to_date_c
cDate add_months_to_date_c( cDate date, int64_t months );
Returns a cDate instance containing a date months later than the date (or earlier if months is negative). If the ending day/month combination does not exist in the resulting month/year, this function will return a date that is the latest valid date.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate date = date_c( 2011, c_Mar, 31 );
cDate res = add_months_to_date_c( date, 13 );
expect_c_( eq_date_c( res, date_c( 2012, c_Apr, 30 ) ) );
res = add_months_to_date_c( date, -13 );
expect_c_( eq_date_c( res, date_c( 2010, c_Feb, 28 ) ) );
return finish_tap_c_();
}
add_years_to_date_c
cDate add_years_to_date_c( cDate date, int64_t years );
Returns a cDate instance containing a date years later than the date (or earlier if years is negative). If the ending day/month combination does not exist in the resulting year (i.e., if the date was Feb 29 and the final year is not a leap year), this function will return a date that is the latest valid date (that is, Feb 28).
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate date = date_c( 2011, c_Mar, 31 );
cDate res = add_years_to_date_c( date, 5 );
expect_c_( eq_date_c( res, date_c( 2016, c_Mar, 31 ) ) );
res = add_years_to_date_c( date, -7 );
expect_c_( eq_date_c( res, date_c( 2004, c_Mar, 31 ) ) );
return finish_tap_c_();
}
diff
days_between_dates_c
int64_t days_between_dates_c( cDate a, cDate b );
Returns the number of days from a to b (which is negative if b is earlier than a). If one of the dates is invalid is the result undefined.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
cDate a;
cDate b;
int64_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
cDate a = date_c( 2012, c_Apr, 8 );
testSlice tests = slice_c_( test,
t_( a, date_c( 2012, c_Jan, 3 ), -96 ),
t_( a, date_c( 2012, c_May, 11 ), 33 )
);
for_each_c_( test const*, t, tests )
{
int64_t days = days_between_dates_c( t->a, t->b );
tap_descf_c( days == t->exp, "days: %"PRIi64, days );
}
return finish_tap_c_();
}
weeks_between_dates_c
int64_t weeks_between_dates_c( cDate a, cDate b );
Returns the number of full weeks from a to b (which is negative if b is earlier than a). If one of the dates is invalid is the result undefined.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
cDate a;
cDate b;
int64_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
cDate a = date_c( 2012, c_Apr, 8 );
testSlice tests = slice_c_( test,
t_( a, date_c( 2011, c_Apr, 8 ), -52 ),
t_( a, date_c( 2012, c_May, 15 ), 5 )
);
for_each_c_( test const*, t, tests )
{
int64_t weeks = weeks_between_dates_c( t->a, t->b );
tap_descf_c( weeks == t->exp, "weeks: %"PRIi64, weeks );
}
return finish_tap_c_();
}
months_between_dates_c
int64_t months_between_dates_c( cDate a, cDate b );
Returns the number of full months from a to b (which is negative if b is earlier than a). If one of the dates is invalid is the result undefined.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
cDate a;
cDate b;
int64_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
cDate a = date_c( 2012, c_Apr, 8 );
testSlice tests = slice_c_( test,
t_( a, date_c( 2012, c_Jan, 3 ), -3 ),
t_( a, date_c( 2012, c_Jun, 11 ), 2 ),
t_( a, date_c( 2012, c_Jan, 28 ), -2 ),
t_( a, date_c( 2012, c_Jun, 1 ), 1 ),
t_( a, date_c( 2010, c_Aug, 30 ), -20 ),
t_( a, date_c( 2014, c_Dec, 1 ), 31 )
);
for_each_c_( test const*, t, tests )
{
int64_t months = months_between_dates_c( t->a, t->b );
tap_descf_c( months == t->exp, "months: %"PRIi64, months );
}
return finish_tap_c_();
}
years_between_dates_c
int64_t years_between_dates_c( cDate a, cDate b );
Returns the number of full years from a to b (which is negative if b is earlier than a). If one of the dates is invalid is the result undefined.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
cDate a;
cDate b;
int64_t exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
cDate a = date_c( 2012, 4, 8 );
testSlice tests = slice_c_( test,
t_( a, date_c( 1983, c_Apr, 8 ), -29 ),
t_( a, date_c( 2020, c_Jan, 19 ), 7 )
);
for_each_c_( test const*, t, tests )
{
int64_t years = years_between_dates_c( t->a, t->b );
tap_descf_c( years == t->exp, "years: %"PRIi64, years );
}
return finish_tap_c_();
}
cmp
cmp_date_c
int cmp_date_c( cDate a, cDate b );
Compares two dates and returns the three possible results:
- <0
-
if a is earlier as b
- 0
-
if both dates are equal
- >0
-
if a is later as b
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
expect_eq_c_( cmp_date_c( local_date_c(), local_date_c() ) );
{
cDate d2014_03_03 = date_c( 2014, c_Mar, 3 );
cDate d2014_03_04 = date_c( 2014, c_Mar, 4 );
expect_lt_c_( cmp_date_c( d2014_03_03, d2014_03_04 ) );
}
{
cDate d2014_03_10 = date_c( 2014, c_Mar, 10 );
cDate d2014_03_09 = date_c( 2014, c_Mar, 9 );
expect_gt_c_( cmp_date_c( d2014_03_10, d2014_03_09 ) );
}
{
cDate d1996_07_11 = date_c( 1996, c_Aug, 11 );
cDate d2015_05_23 = date_c( 2015, c_May, 23 );
expect_lt_c_( cmp_date_c( d1996_07_11, d2015_05_23 ) );
expect_eq_c_( cmp_date_c( d1996_07_11, d1996_07_11 ) );
expect_gt_c_( cmp_date_c( d2015_05_23, d1996_07_11 ) );
}
return finish_tap_c_();
}
early_date_c
cDate early_date_c( cDate a, cDate b );
Returns the earlier of both dates. An invalid date is allways earier as a valid date.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate a = date_c( 1983, c_Dec, 1 );
cDate b = date_c( 1982, c_Jan, 3 );
expect_c_( eq_date_c( early_date_c( a, b ), b ) );
expect_c_( eq_date_c( early_date_c( null_date_c(), b ), null_date_c() ) );
return finish_tap_c_();
}
eq_date_c
bool eq_date_c( cDate a, cDate b );
Returns true if a is equal to b, otherwise returns false.
late_date_c
cDate late_date_c( cDate a, cDate b );
Returns the later of the both dates. A valid date is allways later as an invalid date.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
int main( void )
{
init_tap_c_();
cDate a = date_c( 1983, c_Dec, 1 );
cDate b = date_c( 1982, c_Jan, 3 );
expect_c_( eq_date_c( late_date_c( a, b ), a ) );
expect_c_( eq_date_c( late_date_c( null_date_c(), a ), a ) );
return finish_tap_c_();
}
io
The functions read_date_c and write_date_c are using the following format:
C |
The day of year as a number without a leading character |
1 to 365 |
__C |
The day of year as a number with leading spaces |
1 to 365 |
CCC |
The day of year as a number with leading zeros |
001 to 365 |
D |
The day as a number without a leading character |
1 to 31 |
_D |
The day as a number with a leading space |
1 to 31 |
DD |
The day as a number with a leading zero |
01 to 31 |
E |
The weekday as a number |
1 to 7 |
EEE |
The abbreviated localized weekday name |
Mon to Sun |
EEEE |
The localized weekday name |
Monday to Sunday |
M |
The month as a number without a leading character |
1 to 12 |
_M |
The month as a number with a leading space |
1 to 12 |
MM |
The month as a number with a leading zero |
01 to 12 |
MMM |
The abbreviated localized month name |
Jan' to Dec |
WW |
The ISO week without a leading zero |
W1 to W53 |
WWW |
The ISO week with a leading zero |
W01 to W53 |
XX |
The ISO week date year as a two digit number |
00 to 99 |
XXXX |
The ISO week date year as a four digit number |
like 1878 |
YY |
The year as a two digit number |
00 to 99 |
YYYY |
The year as a four digit number |
like 1878 |
read_date_c
#define read_date_c_( Sca, Date ) \
read_date_c( (Sca), (Date), "" )
bool read_date_c( cScanner sca[static 1],
cDate date[static 1],
char const fmt[static 1] );
Reads a cDate value from a text with a scanner. The function will use C_DateFormat( "YYYY.MM.DD" ) as default format.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
char const* inp;
char const* fmt;
cDate exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
cDate apr01 = date_c( 2013, c_Apr, 1 );
testSlice tests = slice_c_( test,
t_( "20130401", "YYYYMMDD", apr01 ),
t_( "13-4-1", "YY-M-D", apr01 )
);
for_each_c_( test const*, t, tests )
{
cScanner* sca = &cstr_scanner_c_( t->inp );
cDate d = date_c( 1979, 1, 1 );
bool res = read_date_c( sca, &d, t->fmt );
cRecorder* rec = &recorder_c_( 32 );
write_date_c_( rec, d );
tap_descf_c( res, "%s -> %s", t->fmt, turn_into_cstr_c( rec ) );
}
return finish_tap_c_();
}
write_date_c
#define write_date_c_( Rec, Date ) \
write_date_c( (Rec), (Date), "" )
bool write_date_c( cRecorder rec[static 1],
cDate date,
char const fmt[static 1] );
Writes a cDate value into the recorder. The function will use C_DateFormat( "YYYY.MM.DD" ) as default format.
#include "clingo/lang/expect.h"
#include "clingo/time/cDate.h"
TEMP_SLICE_C_(
test,
{
cDate date;
char const* fmt;
char const* exp;
}
)
#define t_( ... ) ((test){__VA_ARGS__})
int main( void )
{
init_tap_c_();
cDate apr01 = date_c( 2013, c_Apr, 1 );
testSlice tests = slice_c_( test,
t_( apr01, "YYYYMMDD", "20130401" ),
t_( apr01, "YY-M-D", "13-4-1" )
);
for_each_c_( test const*, t, tests )
{
cRecorder* rec = &recorder_c_( 32 );
bool res = write_date_c( rec, t->date, t->fmt );
res &= recorded_is_c( rec, t->exp );
tap_descf_c( res, "test: %s -> %s", t->fmt, t->exp );
}
return finish_tap_c_();
}