calendar.c revision 290000
1284990Scy#include "config.h" 2284990Scy 3290000Sglebius#include "ntp_stdlib.h" /* test fail without this include, for some reason */ 4284990Scy#include "ntp_calendar.h" 5284990Scy#include "unity.h" 6284990Scy 7284990Scy#include <string.h> 8284990Scy 9284990Scystatic int leapdays(int year); 10284990Scy 11290000Sglebiusint isGT(int first, int second); 12290000Sglebiusint leapdays(int year); 13290000Sglebiuschar * CalendarFromCalToString(const struct calendar *cal); 14290000Sglebiuschar * CalendarFromIsoToString(const struct isodate *iso); 15290000Sglebiusint IsEqualCal(const struct calendar *expected, const struct calendar *actual); 16290000Sglebiusint IsEqualIso(const struct isodate *expected, const struct isodate *actual); 17290000Sglebiuschar * DateFromCalToString(const struct calendar *cal); 18290000Sglebiuschar * DateFromIsoToString(const struct isodate *iso); 19290000Sglebiusint IsEqualDateCal(const struct calendar *expected, const struct calendar *actual); 20290000Sglebiusint IsEqualDateIso(const struct isodate *expected, const struct isodate *actual); 21290000Sglebiusvoid test_DaySplitMerge(void); 22290000Sglebiusvoid test_SplitYearDays1(void); 23290000Sglebiusvoid test_SplitYearDays2(void); 24290000Sglebiusvoid test_RataDie1(void); 25290000Sglebiusvoid test_LeapYears1(void); 26290000Sglebiusvoid test_LeapYears2(void); 27290000Sglebiusvoid test_RoundTripDate(void); 28290000Sglebiusvoid test_RoundTripYearStart(void); 29290000Sglebiusvoid test_RoundTripMonthStart(void); 30290000Sglebiusvoid test_RoundTripWeekStart(void); 31290000Sglebiusvoid test_RoundTripDayStart(void); 32290000Sglebiusvoid test_IsoCalYearsToWeeks(void); 33290000Sglebiusvoid test_IsoCalWeeksToYearStart(void); 34290000Sglebiusvoid test_IsoCalWeeksToYearEnd(void); 35290000Sglebiusvoid test_DaySecToDate(void); 36284990Scy 37290000Sglebius/* 38290000Sglebius * --------------------------------------------------------------------- 39290000Sglebius * test support stuff 40290000Sglebius * --------------------------------------------------------------------- 41290000Sglebius */ 42290000Sglebiusint 43290000SglebiusisGT(int first, int second) 44290000Sglebius{ 45290000Sglebius if(first > second) { 46290000Sglebius return TRUE; 47290000Sglebius } else { 48290000Sglebius return FALSE; 49284990Scy } 50284990Scy} 51284990Scy 52290000Sglebiusint 53290000Sglebiusleapdays(int year) 54284990Scy{ 55284990Scy if (year % 400 == 0) 56284990Scy return 1; 57284990Scy if (year % 100 == 0) 58284990Scy return 0; 59284990Scy if (year % 4 == 0) 60284990Scy return 1; 61284990Scy return 0; 62284990Scy} 63284990Scy 64290000Sglebiuschar * 65290000SglebiusCalendarFromCalToString( 66290000Sglebius const struct calendar *cal) 67290000Sglebius{ 68290000Sglebius char * str = malloc(sizeof (char) * 100); 69290000Sglebius snprintf(str, 100, "%u-%02u-%02u (%u) %02u:%02u:%02u", 70290000Sglebius cal->year, (u_int)cal->month, (u_int)cal->monthday, 71290000Sglebius cal->yearday, 72290000Sglebius (u_int)cal->hour, (u_int)cal->minute, (u_int)cal->second); 73290000Sglebius str[99] = '\0'; /* paranoia rulez! */ 74290000Sglebius return str; 75284990Scy} 76284990Scy 77290000Sglebiuschar * 78290000SglebiusCalendarFromIsoToString( 79290000Sglebius const struct isodate *iso) 80290000Sglebius{ 81290000Sglebius char * str = emalloc (sizeof (char) * 100); 82290000Sglebius snprintf(str, 100, "%u-W%02u-%02u %02u:%02u:%02u", 83290000Sglebius iso->year, (u_int)iso->week, (u_int)iso->weekday, 84290000Sglebius (u_int)iso->hour, (u_int)iso->minute, (u_int)iso->second); 85290000Sglebius str[99] = '\0'; /* paranoia rulez! */ 86290000Sglebius return str; 87284990Scy} 88284990Scy 89290000Sglebiusint 90290000SglebiusIsEqualCal( 91290000Sglebius const struct calendar *expected, 92290000Sglebius const struct calendar *actual) 93290000Sglebius{ 94290000Sglebius if (expected->year == actual->year && 95290000Sglebius (!expected->yearday || expected->yearday == actual->yearday) && 96290000Sglebius expected->month == actual->month && 97290000Sglebius expected->monthday == actual->monthday && 98290000Sglebius expected->hour == actual->hour && 99290000Sglebius expected->minute == actual->minute && 100290000Sglebius expected->second == actual->second) { 101284990Scy return TRUE; 102284990Scy } else { 103290000Sglebius printf("expected: %s but was %s", 104290000Sglebius CalendarFromCalToString(expected), 105290000Sglebius CalendarFromCalToString(actual)); 106284990Scy return FALSE; 107284990Scy } 108284990Scy} 109284990Scy 110290000Sglebiusint 111290000SglebiusIsEqualIso( 112290000Sglebius const struct isodate *expected, 113290000Sglebius const struct isodate *actual) 114290000Sglebius{ 115290000Sglebius if (expected->year == actual->year && 116290000Sglebius expected->week == actual->week && 117290000Sglebius expected->weekday == actual->weekday && 118290000Sglebius expected->hour == actual->hour && 119290000Sglebius expected->minute == actual->minute && 120290000Sglebius expected->second == actual->second) { 121284990Scy return TRUE; 122284990Scy } else { 123290000Sglebius printf("expected: %s but was %s", 124290000Sglebius CalendarFromIsoToString(expected), 125290000Sglebius CalendarFromIsoToString(actual)); 126284990Scy return FALSE; 127284990Scy } 128284990Scy} 129284990Scy 130290000Sglebiuschar * 131290000SglebiusDateFromCalToString( 132290000Sglebius const struct calendar *cal) 133290000Sglebius{ 134284990Scy 135290000Sglebius char * str = emalloc (sizeof (char) * 100); 136290000Sglebius snprintf(str, 100, "%u-%02u-%02u (%u)", 137290000Sglebius cal->year, (u_int)cal->month, (u_int)cal->monthday, 138290000Sglebius cal->yearday); 139290000Sglebius str[99] = '\0'; /* paranoia rulez! */ 140290000Sglebius return str; 141284990Scy} 142284990Scy 143290000Sglebiuschar * 144290000SglebiusDateFromIsoToString( 145290000Sglebius const struct isodate *iso) 146290000Sglebius{ 147284990Scy 148290000Sglebius char * str = emalloc (sizeof (char) * 100); 149290000Sglebius snprintf(str, 100, "%u-W%02u-%02u", 150290000Sglebius iso->year, (u_int)iso->week, (u_int)iso->weekday); 151290000Sglebius str[99] = '\0'; /* paranoia rulez! */ 152290000Sglebius return str; 153284990Scy} 154284990Scy 155290000Sglebiusint/*BOOL*/ 156290000SglebiusIsEqualDateCal( 157290000Sglebius const struct calendar *expected, 158290000Sglebius const struct calendar *actual) 159290000Sglebius{ 160290000Sglebius if (expected->year == actual->year && 161290000Sglebius (!expected->yearday || expected->yearday == actual->yearday) && 162290000Sglebius expected->month == actual->month && 163290000Sglebius expected->monthday == actual->monthday) { 164284990Scy return TRUE; 165284990Scy } else { 166290000Sglebius printf("expected: %s but was %s", 167290000Sglebius DateFromCalToString(expected), 168290000Sglebius DateFromCalToString(actual)); 169284990Scy return FALSE; 170284990Scy } 171284990Scy} 172284990Scy 173290000Sglebiusint/*BOOL*/ 174290000SglebiusIsEqualDateIso( 175290000Sglebius const struct isodate *expected, 176290000Sglebius const struct isodate *actual) 177290000Sglebius{ 178290000Sglebius if (expected->year == actual->year && 179290000Sglebius expected->week == actual->week && 180290000Sglebius expected->weekday == actual->weekday) { 181284990Scy return TRUE; 182284990Scy } else { 183290000Sglebius printf("expected: %s but was %s", 184290000Sglebius DateFromIsoToString(expected), 185290000Sglebius DateFromIsoToString(actual)); 186284990Scy return FALSE; 187284990Scy } 188284990Scy} 189284990Scy 190284990Scy 191290000Sglebius/* 192290000Sglebius * --------------------------------------------------------------------- 193290000Sglebius * test cases 194290000Sglebius * --------------------------------------------------------------------- 195290000Sglebius */ 196290000Sglebius 197290000Sglebius/* days before month, with a full-year pad at the upper end */ 198284990Scystatic const u_short real_month_table[2][13] = { 199284990Scy /* -*- table for regular years -*- */ 200284990Scy { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 201284990Scy /* -*- table for leap years -*- */ 202284990Scy { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } 203284990Scy}; 204284990Scy 205290000Sglebius/* days in month, with one month wrap-around at both ends */ 206284990Scystatic const u_short real_month_days[2][14] = { 207284990Scy /* -*- table for regular years -*- */ 208284990Scy { 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31 }, 209284990Scy /* -*- table for leap years -*- */ 210284990Scy { 31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31 } 211284990Scy}; 212284990Scy 213290000Sglebius/* test the day/sec join & split ops, making sure that 32bit 214290000Sglebius * intermediate results would definitely overflow and the hi DWORD of 215290000Sglebius * the 'vint64' is definitely needed. 216290000Sglebius */ 217290000Sglebiusvoid 218290000Sglebiustest_DaySplitMerge(void) { 219284990Scy int32 day,sec; 220284990Scy for (day = -1000000; day <= 1000000; day += 100) { 221284990Scy for (sec = -100000; sec <= 186400; sec += 10000) { 222290000Sglebius vint64 merge; 223290000Sglebius ntpcal_split split; 224290000Sglebius int32 eday; 225290000Sglebius int32 esec; 226284990Scy 227290000Sglebius merge = ntpcal_dayjoin(day, sec); 228290000Sglebius split = ntpcal_daysplit(&merge); 229290000Sglebius eday = day; 230290000Sglebius esec = sec; 231290000Sglebius 232284990Scy while (esec >= 86400) { 233284990Scy eday += 1; 234284990Scy esec -= 86400; 235284990Scy } 236284990Scy while (esec < 0) { 237284990Scy eday -= 1; 238284990Scy esec += 86400; 239284990Scy } 240284990Scy 241284990Scy TEST_ASSERT_EQUAL(eday, split.hi); 242284990Scy TEST_ASSERT_EQUAL(esec, split.lo); 243284990Scy } 244284990Scy } 245284990Scy} 246284990Scy 247290000Sglebiusvoid 248290000Sglebiustest_SplitYearDays1(void) { 249284990Scy int32 eyd; 250284990Scy for (eyd = -1; eyd <= 365; eyd++) { 251284990Scy ntpcal_split split = ntpcal_split_yeardays(eyd, 0); 252284990Scy if (split.lo >= 0 && split.hi >= 0) { 253290000Sglebius TEST_ASSERT_TRUE(isGT(12,split.hi)); 254290000Sglebius TEST_ASSERT_TRUE(isGT(real_month_days[0][split.hi+1], split.lo)); 255284990Scy int32 tyd = real_month_table[0][split.hi] + split.lo; 256284990Scy TEST_ASSERT_EQUAL(eyd, tyd); 257284990Scy } else 258284990Scy TEST_ASSERT_TRUE(eyd < 0 || eyd > 364); 259284990Scy } 260284990Scy} 261284990Scy 262290000Sglebiusvoid 263290000Sglebiustest_SplitYearDays2(void) { 264284990Scy int32 eyd; 265284990Scy for (eyd = -1; eyd <= 366; eyd++) { 266284990Scy ntpcal_split split = ntpcal_split_yeardays(eyd, 1); 267284990Scy if (split.lo >= 0 && split.hi >= 0) { 268290000Sglebius /* basic checks do not work on compunds :( */ 269290000Sglebius /* would like: TEST_ASSERT_TRUE(12 > split.hi); */ 270290000Sglebius TEST_ASSERT_TRUE(isGT(12,split.hi)); 271290000Sglebius TEST_ASSERT_TRUE(isGT(real_month_days[1][split.hi+1], split.lo)); 272284990Scy int32 tyd = real_month_table[1][split.hi] + split.lo; 273284990Scy TEST_ASSERT_EQUAL(eyd, tyd); 274284990Scy } else 275284990Scy TEST_ASSERT_TRUE(eyd < 0 || eyd > 365); 276284990Scy } 277284990Scy} 278284990Scy 279290000Sglebiusvoid 280290000Sglebiustest_RataDie1(void) { 281290000Sglebius int32 testDate = 1; /* 0001-01-01 (proleptic date) */ 282284990Scy struct calendar expected = { 1, 1, 1, 1 }; 283284990Scy struct calendar actual; 284284990Scy 285284990Scy ntpcal_rd_to_date(&actual, testDate); 286290000Sglebius TEST_ASSERT_TRUE(IsEqualDateCal(&expected, &actual)); 287284990Scy} 288284990Scy 289290000Sglebius/* check last day of february for first 10000 years */ 290290000Sglebiusvoid 291290000Sglebiustest_LeapYears1(void) { 292284990Scy struct calendar dateIn, dateOut; 293284990Scy 294284990Scy for (dateIn.year = 1; dateIn.year < 10000; ++dateIn.year) { 295284990Scy dateIn.month = 2; 296284990Scy dateIn.monthday = 28 + leapdays(dateIn.year); 297284990Scy dateIn.yearday = 31 + dateIn.monthday; 298284990Scy 299284990Scy ntpcal_rd_to_date(&dateOut, ntpcal_date_to_rd(&dateIn)); 300284990Scy 301290000Sglebius TEST_ASSERT_TRUE(IsEqualDateCal(&dateIn, &dateOut)); 302284990Scy } 303284990Scy} 304284990Scy 305290000Sglebius/* check first day of march for first 10000 years */ 306290000Sglebiusvoid 307290000Sglebiustest_LeapYears2(void) { 308284990Scy struct calendar dateIn, dateOut; 309284990Scy 310284990Scy for (dateIn.year = 1; dateIn.year < 10000; ++dateIn.year) { 311284990Scy dateIn.month = 3; 312284990Scy dateIn.monthday = 1; 313284990Scy dateIn.yearday = 60 + leapdays(dateIn.year); 314284990Scy 315284990Scy ntpcal_rd_to_date(&dateOut, ntpcal_date_to_rd(&dateIn)); 316290000Sglebius TEST_ASSERT_TRUE(IsEqualDateCal(&dateIn, &dateOut)); 317284990Scy } 318284990Scy} 319284990Scy 320290000Sglebius/* Full roundtrip from 1601-01-01 to 2400-12-31 321290000Sglebius * checks sequence of rata die numbers and validates date output 322290000Sglebius * (since the input is all nominal days of the calendar in that range 323290000Sglebius * and the result of the inverse calculation must match the input no 324290000Sglebius * invalid output can occur.) 325290000Sglebius */ 326290000Sglebiusvoid 327290000Sglebiustest_RoundTripDate(void) { 328284990Scy struct calendar truDate, expDate = { 1600, 0, 12, 31 };; 329290000Sglebius int leaps; 330284990Scy int32 truRdn, expRdn = ntpcal_date_to_rd(&expDate); 331284990Scy 332284990Scy while (expDate.year < 2400) { 333284990Scy expDate.year++; 334284990Scy expDate.month = 0; 335284990Scy expDate.yearday = 0; 336284990Scy leaps = leapdays(expDate.year); 337284990Scy while (expDate.month < 12) { 338284990Scy expDate.month++; 339284990Scy expDate.monthday = 0; 340284990Scy while (expDate.monthday < real_month_days[leaps][expDate.month]) { 341284990Scy expDate.monthday++; 342284990Scy expDate.yearday++; 343284990Scy expRdn++; 344284990Scy 345284990Scy truRdn = ntpcal_date_to_rd(&expDate); 346284990Scy TEST_ASSERT_EQUAL(expRdn, truRdn); 347284990Scy 348284990Scy ntpcal_rd_to_date(&truDate, truRdn); 349290000Sglebius TEST_ASSERT_TRUE(IsEqualDateCal(&expDate, &truDate)); 350284990Scy } 351284990Scy } 352284990Scy } 353284990Scy} 354284990Scy 355290000Sglebius/* Roundtrip testing on calyearstart */ 356290000Sglebiusvoid 357290000Sglebiustest_RoundTripYearStart(void) { 358284990Scy static const time_t pivot = 0; 359284990Scy u_int32 ntp, expys, truys; 360284990Scy struct calendar date; 361284990Scy 362284990Scy for (ntp = 0; ntp < 0xFFFFFFFFu - 30000000u; ntp += 30000000u) { 363284990Scy truys = calyearstart(ntp, &pivot); 364284990Scy ntpcal_ntp_to_date(&date, ntp, &pivot); 365284990Scy date.month = date.monthday = 1; 366284990Scy date.hour = date.minute = date.second = 0; 367284990Scy expys = ntpcal_date_to_ntp(&date); 368284990Scy TEST_ASSERT_EQUAL(expys, truys); 369284990Scy } 370284990Scy} 371284990Scy 372290000Sglebius/* Roundtrip testing on calmonthstart */ 373290000Sglebiusvoid 374290000Sglebiustest_RoundTripMonthStart(void) { 375284990Scy static const time_t pivot = 0; 376284990Scy u_int32 ntp, expms, trums; 377284990Scy struct calendar date; 378284990Scy 379284990Scy for (ntp = 0; ntp < 0xFFFFFFFFu - 2000000u; ntp += 2000000u) { 380284990Scy trums = calmonthstart(ntp, &pivot); 381284990Scy ntpcal_ntp_to_date(&date, ntp, &pivot); 382284990Scy date.monthday = 1; 383284990Scy date.hour = date.minute = date.second = 0; 384284990Scy expms = ntpcal_date_to_ntp(&date); 385284990Scy TEST_ASSERT_EQUAL(expms, trums); 386284990Scy } 387284990Scy} 388284990Scy 389290000Sglebius/* Roundtrip testing on calweekstart */ 390290000Sglebiusvoid 391290000Sglebiustest_RoundTripWeekStart(void) { 392284990Scy static const time_t pivot = 0; 393284990Scy u_int32 ntp, expws, truws; 394284990Scy struct isodate date; 395284990Scy 396284990Scy for (ntp = 0; ntp < 0xFFFFFFFFu - 600000u; ntp += 600000u) { 397284990Scy truws = calweekstart(ntp, &pivot); 398284990Scy isocal_ntp_to_date(&date, ntp, &pivot); 399284990Scy date.hour = date.minute = date.second = 0; 400284990Scy date.weekday = 1; 401284990Scy expws = isocal_date_to_ntp(&date); 402284990Scy TEST_ASSERT_EQUAL(expws, truws); 403284990Scy } 404284990Scy} 405284990Scy 406290000Sglebius/* Roundtrip testing on caldaystart */ 407290000Sglebiusvoid 408290000Sglebiustest_RoundTripDayStart(void) { 409284990Scy static const time_t pivot = 0; 410284990Scy u_int32 ntp, expds, truds; 411284990Scy struct calendar date; 412284990Scy 413284990Scy for (ntp = 0; ntp < 0xFFFFFFFFu - 80000u; ntp += 80000u) { 414284990Scy truds = caldaystart(ntp, &pivot); 415284990Scy ntpcal_ntp_to_date(&date, ntp, &pivot); 416284990Scy date.hour = date.minute = date.second = 0; 417284990Scy expds = ntpcal_date_to_ntp(&date); 418284990Scy TEST_ASSERT_EQUAL(expds, truds); 419284990Scy } 420290000Sglebius} 421284990Scy 422290000Sglebius/* --------------------------------------------------------------------- 423290000Sglebius * ISO8601 week calendar internals 424290000Sglebius * 425290000Sglebius * The ISO8601 week calendar implementation is simple in the terms of 426290000Sglebius * the math involved, but the implementation of the calculations must 427290000Sglebius * take care of a few things like overflow, floor division, and sign 428290000Sglebius * corrections. 429290000Sglebius * 430290000Sglebius * Most of the functions are straight forward, but converting from years 431290000Sglebius * to weeks and from weeks to years warrants some extra tests. These use 432290000Sglebius * an independent reference implementation of the conversion from years 433290000Sglebius * to weeks. 434290000Sglebius * --------------------------------------------------------------------- 435290000Sglebius */ 436290000Sglebius 437290000Sglebius/* helper / reference implementation for the first week of year in the 438290000Sglebius * ISO8601 week calendar. This is based on the reference definition of 439290000Sglebius * the ISO week calendar start: The Monday closest to January,1st of the 440290000Sglebius * corresponding year in the Gregorian calendar. 441290000Sglebius */ 442290000Sglebiusstatic int32_t 443290000Sglebiusrefimpl_WeeksInIsoYears( 444290000Sglebius int32_t years) 445290000Sglebius{ 446290000Sglebius int32_t days, weeks; 447290000Sglebius days = ntpcal_weekday_close( 448290000Sglebius ntpcal_days_in_years(years) + 1, 449290000Sglebius CAL_MONDAY) - 1; 450290000Sglebius /* the weekday functions operate on RDN, while we want elapsed 451290000Sglebius * units here -- we have to add / sub 1 in the midlle / at the 452290000Sglebius * end of the operation that gets us the first day of the ISO 453290000Sglebius * week calendar day. 454290000Sglebius */ 455290000Sglebius weeks = days / 7; 456290000Sglebius days = days % 7; 457290000Sglebius TEST_ASSERT_EQUAL(0, days); /* paranoia check... */ 458290000Sglebius return weeks; 459290000Sglebius} 460290000Sglebius 461290000Sglebius/* The next tests loop over 5000yrs, but should still be very fast. If 462290000Sglebius * they are not, the calendar needs a better implementation... 463290000Sglebius */ 464290000Sglebiusvoid 465290000Sglebiustest_IsoCalYearsToWeeks(void) { 466290000Sglebius int32_t years; 467290000Sglebius int32_t wref, wcal; 468290000Sglebius for (years = -1000; years < 4000; ++years) { 469290000Sglebius /* get number of weeks before years (reference) */ 470290000Sglebius wref = refimpl_WeeksInIsoYears(years); 471290000Sglebius /* get number of weeks before years (object-under-test) */ 472290000Sglebius wcal = isocal_weeks_in_years(years); 473290000Sglebius TEST_ASSERT_EQUAL(wref, wcal); 474290000Sglebius } 475290000Sglebius} 476290000Sglebius 477290000Sglebiusvoid 478290000Sglebiustest_IsoCalWeeksToYearStart(void) { 479290000Sglebius int32_t years; 480290000Sglebius int32_t wref; 481290000Sglebius ntpcal_split ysplit; 482290000Sglebius for (years = -1000; years < 4000; ++years) { 483290000Sglebius /* get number of weeks before years (reference) */ 484290000Sglebius wref = refimpl_WeeksInIsoYears(years); 485290000Sglebius /* reverse split */ 486290000Sglebius ysplit = isocal_split_eraweeks(wref); 487290000Sglebius /* check invariants: same year, week 0 */ 488290000Sglebius TEST_ASSERT_EQUAL(years, ysplit.hi); 489290000Sglebius TEST_ASSERT_EQUAL(0, ysplit.lo); 490290000Sglebius } 491290000Sglebius} 492290000Sglebius 493290000Sglebiusvoid 494290000Sglebiustest_IsoCalWeeksToYearEnd(void) { 495290000Sglebius int32_t years; 496290000Sglebius int32_t wref; 497290000Sglebius ntpcal_split ysplit; 498290000Sglebius for (years = -1000; years < 4000; ++years) { 499290000Sglebius /* get last week of previous year */ 500290000Sglebius wref = refimpl_WeeksInIsoYears(years) - 1; 501290000Sglebius /* reverse split */ 502290000Sglebius ysplit = isocal_split_eraweeks(wref); 503290000Sglebius /* check invariants: previous year, week 51 or 52 */ 504290000Sglebius TEST_ASSERT_EQUAL(years-1, ysplit.hi); 505290000Sglebius TEST_ASSERT(ysplit.lo == 51 || ysplit.lo == 52); 506290000Sglebius } 507290000Sglebius} 508290000Sglebius 509290000Sglebiusvoid 510290000Sglebiustest_DaySecToDate(void) { 511290000Sglebius struct calendar cal; 512290000Sglebius int32_t days; 513290000Sglebius 514290000Sglebius days = ntpcal_daysec_to_date(&cal, -86400); 515290000Sglebius TEST_ASSERT_MESSAGE((days==-1 && cal.hour==0 && cal.minute==0 && cal.second==0), 516290000Sglebius "failed for -86400"); 517290000Sglebius 518290000Sglebius days = ntpcal_daysec_to_date(&cal, -86399); 519290000Sglebius TEST_ASSERT_MESSAGE((days==-1 && cal.hour==0 && cal.minute==0 && cal.second==1), 520290000Sglebius "failed for -86399"); 521290000Sglebius 522290000Sglebius days = ntpcal_daysec_to_date(&cal, -1); 523290000Sglebius TEST_ASSERT_MESSAGE((days==-1 && cal.hour==23 && cal.minute==59 && cal.second==59), 524290000Sglebius "failed for -1"); 525290000Sglebius 526290000Sglebius days = ntpcal_daysec_to_date(&cal, 0); 527290000Sglebius TEST_ASSERT_MESSAGE((days==0 && cal.hour==0 && cal.minute==0 && cal.second==0), 528290000Sglebius "failed for 0"); 529290000Sglebius 530290000Sglebius days = ntpcal_daysec_to_date(&cal, 1); 531290000Sglebius TEST_ASSERT_MESSAGE((days==0 && cal.hour==0 && cal.minute==0 && cal.second==1), 532290000Sglebius "failed for 1"); 533290000Sglebius 534290000Sglebius days = ntpcal_daysec_to_date(&cal, 86399); 535290000Sglebius TEST_ASSERT_MESSAGE((days==0 && cal.hour==23 && cal.minute==59 && cal.second==59), 536290000Sglebius "failed for 86399"); 537290000Sglebius 538290000Sglebius days = ntpcal_daysec_to_date(&cal, 86400); 539290000Sglebius TEST_ASSERT_MESSAGE((days==1 && cal.hour==0 && cal.minute==0 && cal.second==0), 540290000Sglebius "failed for 86400"); 541290000Sglebius} 542