From 7b7645f060949574c86b2b1e881c1d0fea1f96fd Mon Sep 17 00:00:00 2001 From: skarg Date: Tue, 23 Jan 2007 21:43:26 +0000 Subject: [PATCH] Added functions to assist Load Control object. --- bacnet-stack/datetime.c | 197 +++++++++++++++++++++++++++++++++++++- bacnet-stack/datetime.h | 3 + bacnet-stack/datetime.ide | Bin 30644 -> 30644 bytes 3 files changed, 198 insertions(+), 2 deletions(-) diff --git a/bacnet-stack/datetime.c b/bacnet-stack/datetime.c index 96fe851d..9d23448e 100644 --- a/bacnet-stack/datetime.c +++ b/bacnet-stack/datetime.c @@ -87,7 +87,7 @@ static uint32_t days_since_epoch(uint16_t year, uint8_t month, uint8_t day) } for (months = 1; months < month; months++) { - days += month_days(months,year); + days += month_days(years, months); } days += (day - 1); } @@ -95,6 +95,45 @@ static uint32_t days_since_epoch(uint16_t year, uint8_t month, uint8_t day) return (days); } +static void days_since_epoch_into_ymd( + uint32_t days, + uint16_t *pYear, + uint8_t *pMonth, + uint8_t *pDay) +{ + int year = 1900; + int month = 1; + int day = 1; + + while (days >= 365) + { + if ((is_leap_year(year)) && days == 365) + break; + days -= 365; + if (is_leap_year(year)) + --days; + year++; + } + + while (days >= month_days(year, month)) + { + days -= month_days(year, month); + month++; + } + + day += days; + + if (pYear) + *pYear = year; + if (pMonth) + *pMonth = month; + if (pDay) + *pDay = day; + + return; +} + + /* Jan 1, 1900 is a Monday */ /* wday 1=Monday...7=Sunday */ static uint8_t day_of_week(uint16_t year, uint8_t month, uint8_t day) @@ -243,11 +282,131 @@ void datetime_set_values(BACNET_DATE_TIME * bdatetime, } } +static uint32_t seconds_since_midnight(uint8_t hours, uint8_t minutes, + uint8_t seconds) +{ + return ((hours * 60 * 60) + (minutes * 60) + seconds); +} + +static void seconds_since_midnight_into_hms(uint32_t seconds, + uint8_t * pHours, + uint8_t *pMinutes, + uint8_t *pSeconds) +{ + uint8_t hour = 0; + uint8_t minute = 0; + + hour = seconds / (60 * 60); + seconds -= (hour * 60 * 60); + minute = seconds / 60; + seconds -= (minute * 60); + + if (pHours) + *pHours = hour; + if (pMinutes) + *pMinutes = minute; + if (pSeconds) + *pSeconds = seconds; +} + +void datetime_add_minutes(BACNET_DATE_TIME * bdatetime, uint32_t minutes) +{ + uint32_t bdatetime_minutes = 0; + uint32_t bdatetime_days = 0; + uint32_t days = 0; + + /* convert bdatetime to seconds and days */ + bdatetime_minutes = seconds_since_midnight( + bdatetime->time.hour, + bdatetime->time.min, + bdatetime->time.sec) / 60; + bdatetime_days = days_since_epoch( + bdatetime->date.year, + bdatetime->date.month, + bdatetime->date.day); + + /* add */ + days = minutes / (24*60); + bdatetime_days += days; + minutes -= (days * 24 * 60); + bdatetime_minutes += minutes; + days = bdatetime_minutes / (24*60); + bdatetime_days += days; + + /* convert bdatetime from seconds and days */ + seconds_since_midnight_into_hms(bdatetime_minutes * 60, + &bdatetime->time.hour, + &bdatetime->time.min, + &bdatetime->time.sec); + days_since_epoch_into_ymd( + bdatetime_days, + &bdatetime->date.year, + &bdatetime->date.month, + &bdatetime->date.day); + bdatetime->date.wday = day_of_week( + bdatetime->date.year, + bdatetime->date.month, + bdatetime->date.day); +} + #ifdef TEST #include #include #include "ctest.h" +void testBACnetDateTimeAdd(Test * pTest) +{ + BACNET_DATE_TIME bdatetime, test_bdatetime; + uint32_t minutes = 0; + int diff = 0; + + datetime_set_values(&bdatetime, 1900,1,1,0,0,0,0); + datetime_copy(&test_bdatetime,&bdatetime); + datetime_add_minutes(&bdatetime, minutes); + diff = datetime_compare(&test_bdatetime, &bdatetime); + ct_test(pTest, diff == 0); + + datetime_set_values(&bdatetime, 1900,1,1,0,0,0,0); + datetime_add_minutes(&bdatetime, 60); + datetime_set_values(&test_bdatetime, 1900,1,1,1,0,0,0); + diff = datetime_compare(&test_bdatetime, &bdatetime); + ct_test(pTest, diff == 0); + + datetime_set_values(&bdatetime, 1900,1,1,0,0,0,0); + datetime_add_minutes(&bdatetime, (24*60)); + datetime_set_values(&test_bdatetime, 1900,1,2,0,0,0,0); + diff = datetime_compare(&test_bdatetime, &bdatetime); + ct_test(pTest, diff == 0); + + datetime_set_values(&bdatetime, 1900,1,1,0,0,0,0); + datetime_add_minutes(&bdatetime, (31*24*60)); + datetime_set_values(&test_bdatetime, 1900,2,1,0,0,0,0); + diff = datetime_compare(&test_bdatetime, &bdatetime); + ct_test(pTest, diff == 0); +} + + + +void testBACnetDateTimeSeconds(Test * pTest) +{ + uint8_t hour = 0, minute = 0, second = 0; + uint8_t test_hour = 0, test_minute = 0, test_second = 0; + uint32_t seconds = 0, test_seconds; + + for (hour = 0; hour < 24; hour++) { + for (minute = 0; minute < 60; minute+=3) { + for (second = 0; second < 60; second+=17) { + seconds = seconds_since_midnight(hour, minute, second); + seconds_since_midnight_into_hms(seconds, + &test_hour, &test_minute, &test_second); + test_seconds = seconds_since_midnight( + test_hour, test_minute, test_second); + ct_test(pTest, seconds == test_seconds); + } + } + } +} + void testBACnetDate(Test * pTest) { BACNET_DATE bdate1, bdate2; @@ -425,6 +584,35 @@ void testBACnetDateTime(Test * pTest) return; } +void testDateEpoch(Test * pTest) +{ + uint32_t days = 0; + uint16_t year = 0, test_year = 0; + uint8_t month = 0, test_month = 0; + uint8_t day = 0, test_day = 0; + + days = days_since_epoch(1900,1,1); + ct_test(pTest, days == 0); + days_since_epoch_into_ymd(days, &year, &month, &day); + ct_test(pTest, year == 1900); + ct_test(pTest, month == 1); + ct_test(pTest, day == 1); + + + for (year = 1900; year <= 2154; year++) { + for (month = 1; month <= 12; month++) { + for (day = 1; day <= month_days(year, month); day++) { + days = days_since_epoch(year, month, day); + days_since_epoch_into_ymd(days, + &test_year, &test_month, &test_day); + ct_test(pTest, year == test_year); + ct_test(pTest, month == test_month); + ct_test(pTest, day == test_day); + } + } + } +} + void testBACnetDayOfWeek(Test * pTest) { uint8_t dow = 0; @@ -451,7 +639,6 @@ void testBACnetDayOfWeek(Test * pTest) dow = day_of_week(2007, 1, 31); ct_test(pTest, dow == 3); - } #ifdef TEST_DATE_TIME @@ -470,6 +657,12 @@ int main(void) assert(rc); rc = ct_addTestFunction(pTest, testBACnetDayOfWeek); assert(rc); + rc = ct_addTestFunction(pTest, testDateEpoch); + assert(rc); + rc = ct_addTestFunction(pTest, testBACnetDateTimeSeconds); + assert(rc); + rc = ct_addTestFunction(pTest, testBACnetDateTimeAdd); + assert(rc); ct_setStream(pTest, stdout); ct_run(pTest); diff --git a/bacnet-stack/datetime.h b/bacnet-stack/datetime.h index ea1b7076..b091aafa 100644 --- a/bacnet-stack/datetime.h +++ b/bacnet-stack/datetime.h @@ -91,6 +91,9 @@ extern "C" { BACNET_DATE_TIME * datetime1, BACNET_DATE_TIME * datetime2); + /* utility add function */ + void datetime_add_minutes(BACNET_DATE_TIME * bdatetime, uint32_t minutes); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bacnet-stack/datetime.ide b/bacnet-stack/datetime.ide index 2c329d3b92a5786a1773cf72a28a1446a6879a91..cd3848511cd8d7488d9de9145aafe5c6fa3801a0 100644 GIT binary patch delta 2697 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