# HG changeset patch # User Laurent Bessard # Date 1361655517 -3600 # Node ID 91fe9690080099f1f6f572be5d5a4f0ab74aa74d # Parent e3ca0f4d47b3241087a5c0f29468348c2aa9924b Fixed bug in DATE_AND_TIME_TO_TIME_OF_DAY and DATE_AND_TIME_TO_DATE when date and time is before 1970-01-01-00:00:00 diff -r e3ca0f4d47b3 -r 91fe96900800 lib/iec_std_lib.h --- a/lib/iec_std_lib.h Wed Dec 19 12:25:56 2012 +0100 +++ b/lib/iec_std_lib.h Sat Feb 23 22:38:37 2013 +0100 @@ -224,7 +224,8 @@ } #define EPOCH_YEAR 1970 -#define SECONDS_PER_HOUR (60 * 60) +#define SECONDS_PER_MINUTE 60 +#define SECONDS_PER_HOUR (60 * SECONDS_PER_MINUTE) #define SECONDS_PER_DAY (24 * SECONDS_PER_HOUR) #define __isleap(year) \ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) @@ -545,15 +546,15 @@ div_t days; /*t#5d14h12m18s3.5ms*/ res = __INIT_STRING; - days = div(IN.tv_sec ,86400); + days = div(IN.tv_sec, SECONDS_PER_DAY); if(!days.rem && IN.tv_nsec == 0){ res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd", days.quot); }else{ - div_t hours = div(days.rem, 3600); + div_t hours = div(days.rem, SECONDS_PER_HOUR); if(!hours.rem && IN.tv_nsec == 0){ res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh", days.quot, hours.quot); }else{ - div_t minuts = div(hours.rem, 60); + div_t minuts = div(hours.rem, SECONDS_PER_MINUTE); if(!minuts.rem && IN.tv_nsec == 0){ res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh%dm", days.quot, hours.quot, minuts.quot); }else{ @@ -637,8 +638,16 @@ /* [ANY_DATE | TIME] _TO_ [ANY_DATE | TIME] */ /**********************************************/ -static inline TOD __date_and_time_to_time_of_day(DT IN) {return (TOD){IN.tv_sec % (24*60*60), IN.tv_nsec};} -static inline DATE __date_and_time_to_date(DT IN){return (DATE){IN.tv_sec - (IN.tv_sec % (24*60*60)), 0};} +static inline TOD __date_and_time_to_time_of_day(DT IN) { + return (TOD){ + IN.tv_sec % SECONDS_PER_DAY + (IN.tv_sec < 0 ? SECONDS_PER_DAY : 0), + IN.tv_nsec}; +} +static inline DATE __date_and_time_to_date(DT IN){ + return (DATE){ + IN.tv_sec - IN.tv_sec % SECONDS_PER_DAY - (IN.tv_sec < 0 ? SECONDS_PER_DAY : 0), + 0}; +} /*****************/ /* FROM/TO BCD */