datetime.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | //----------------------------------------------------------------------------- | ||
| 2 | // datetime.c | ||
| 3 | // | ||
| 4 | // Project: EPA SWMM5 | ||
| 5 | // Version: 5.2 | ||
| 6 | // Date: 11/01/21 (Build 5.2.0) | ||
| 7 | // Author: L. Rossman | ||
| 8 | // | ||
| 9 | // DateTime functions. | ||
| 10 | // | ||
| 11 | // Update History | ||
| 12 | // ============== | ||
| 13 | // Build 5.1.011: | ||
| 14 | // - decodeTime() no longer rounds up. | ||
| 15 | // - New getTimeStamp function added. | ||
| 16 | //----------------------------------------------------------------------------- | ||
| 17 | #define _CRT_SECURE_NO_DEPRECATE | ||
| 18 | |||
| 19 | #include <math.h> | ||
| 20 | #include <string.h> | ||
| 21 | #include <stdlib.h> | ||
| 22 | #include <stdio.h> | ||
| 23 | #include "datetime.h" | ||
| 24 | |||
| 25 | // Macro to convert charcter x to upper case | ||
| 26 | #define UCHAR(x) (((x) >= 'a' && (x) <= 'z') ? ((x)&~32) : (x)) | ||
| 27 | |||
| 28 | //----------------------------------------------------------------------------- | ||
| 29 | // Constants | ||
| 30 | //----------------------------------------------------------------------------- | ||
| 31 | static const char* MonthTxt[] = | ||
| 32 | {"JAN", "FEB", "MAR", "APR", | ||
| 33 | "MAY", "JUN", "JUL", "AUG", | ||
| 34 | "SEP", "OCT", "NOV", "DEC"}; | ||
| 35 | static const int DaysPerMonth[2][12] = // days per month | ||
| 36 | {{31, 28, 31, 30, 31, 30, // normal years | ||
| 37 | 31, 31, 30, 31, 30, 31}, | ||
| 38 | {31, 29, 31, 30, 31, 30, // leap years | ||
| 39 | 31, 31, 30, 31, 30, 31}}; | ||
| 40 | static const int DateDelta = 693594; // days since 01/01/00 | ||
| 41 | static const double SecsPerDay = 86400.; // seconds per day | ||
| 42 | |||
| 43 | //----------------------------------------------------------------------------- | ||
| 44 | // Shared variables | ||
| 45 | //----------------------------------------------------------------------------- | ||
| 46 | static int DateFormat; | ||
| 47 | |||
| 48 | |||
| 49 | //============================================================================= | ||
| 50 | |||
| 51 | 20398049 | void divMod(int n, int d, int* result, int* remainder) | |
| 52 | |||
| 53 | // Input: n = numerator | ||
| 54 | // d = denominator | ||
| 55 | // Output: result = integer part of n/d | ||
| 56 | // remainder = remainder of n/d | ||
| 57 | // Purpose: finds integer part and remainder of n/d. | ||
| 58 | |||
| 59 | { | ||
| 60 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20398049 times.
|
20398049 | if (d == 0) |
| 61 | { | ||
| 62 | ✗ | *result = 0; | |
| 63 | ✗ | *remainder = 0; | |
| 64 | } | ||
| 65 | else | ||
| 66 | { | ||
| 67 | 20398049 | *result = n/d; | |
| 68 | 20398049 | *remainder = n - d*(*result); | |
| 69 | } | ||
| 70 | 20398049 | } | |
| 71 | |||
| 72 | //============================================================================= | ||
| 73 | |||
| 74 | 4202559 | int isLeapYear(int year) | |
| 75 | |||
| 76 | // Input: year = a year | ||
| 77 | // Output: returns 1 if year is a leap year, 0 if not | ||
| 78 | // Purpose: determines if year is a leap year. | ||
| 79 | |||
| 80 | { | ||
| 81 |
2/2✓ Branch 0 taken 417356 times.
✓ Branch 1 taken 3785203 times.
|
4202559 | if ((year % 4 == 0) |
| 82 |
2/2✓ Branch 0 taken 1559 times.
✓ Branch 1 taken 415797 times.
|
417356 | && ((year % 100 != 0) |
| 83 |
1/2✓ Branch 0 taken 1559 times.
✗ Branch 1 not taken.
|
417356 | || (year % 400 == 0))) return 1; |
| 84 | 3785203 | else return 0; | |
| 85 | } | ||
| 86 | |||
| 87 | //============================================================================= | ||
| 88 | |||
| 89 | 7786 | int datetime_findMonth(char* month) | |
| 90 | |||
| 91 | // Input: month = month of year as character string | ||
| 92 | // Output: returns: month of year as a number (1-12) | ||
| 93 | // Purpose: finds number (1-12) of month. | ||
| 94 | |||
| 95 | { | ||
| 96 | int i; | ||
| 97 |
2/2✓ Branch 0 taken 50676 times.
✓ Branch 1 taken 12 times.
|
50688 | for (i = 0; i < 12; i++) |
| 98 | { | ||
| 99 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 50676 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 11036 times.
✓ Branch 5 taken 39640 times.
|
50676 | if (UCHAR(month[0]) == MonthTxt[i][0] |
| 100 |
5/6✓ Branch 0 taken 11012 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 11012 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9070 times.
✓ Branch 5 taken 1966 times.
|
11036 | && UCHAR(month[1]) == MonthTxt[i][1] |
| 101 |
4/6✓ Branch 0 taken 9070 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9070 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7774 times.
✓ Branch 5 taken 1296 times.
|
9070 | && UCHAR(month[2]) == MonthTxt[i][2]) return i+1; |
| 102 | } | ||
| 103 | 12 | return 0; | |
| 104 | } | ||
| 105 | |||
| 106 | //============================================================================= | ||
| 107 | |||
| 108 | 281716 | DateTime datetime_encodeDate(int year, int month, int day) | |
| 109 | |||
| 110 | // Input: year = a year | ||
| 111 | // month = a month (1 to 12) | ||
| 112 | // day = a day of month | ||
| 113 | // Output: returns encoded value of year-month-day | ||
| 114 | // Purpose: encodes year-month-day to a DateTime value. | ||
| 115 | |||
| 116 | { | ||
| 117 | int i, j; | ||
| 118 | 281716 | i = isLeapYear(year); | |
| 119 |
1/2✓ Branch 0 taken 281716 times.
✗ Branch 1 not taken.
|
281716 | if ((year >= 1) |
| 120 |
1/2✓ Branch 0 taken 281716 times.
✗ Branch 1 not taken.
|
281716 | && (year <= 9999) |
| 121 |
1/2✓ Branch 0 taken 281716 times.
✗ Branch 1 not taken.
|
281716 | && (month >= 1) |
| 122 |
1/2✓ Branch 0 taken 281716 times.
✗ Branch 1 not taken.
|
281716 | && (month <= 12) |
| 123 |
1/2✓ Branch 0 taken 281716 times.
✗ Branch 1 not taken.
|
281716 | && (day >= 1) |
| 124 |
1/2✓ Branch 0 taken 281716 times.
✗ Branch 1 not taken.
|
281716 | && (day <= DaysPerMonth[i][month-1])) |
| 125 | { | ||
| 126 |
2/2✓ Branch 0 taken 1337041 times.
✓ Branch 1 taken 281716 times.
|
1618757 | for (j = 0; j < month-1; j++) day += DaysPerMonth[i][j]; |
| 127 | 281716 | i = year - 1; | |
| 128 | 281716 | i = i*365 + i/4 - i/100 + i/400 + day - DateDelta; | |
| 129 | 281716 | return i; | |
| 130 | } | ||
| 131 | ✗ | else return -DateDelta; | |
| 132 | } | ||
| 133 | |||
| 134 | //============================================================================= | ||
| 135 | |||
| 136 | 248945 | DateTime datetime_encodeTime(int hour, int minute, int second) | |
| 137 | |||
| 138 | // Input: hour = hour of day (0-24) | ||
| 139 | // minute = minute of hour (0-60) | ||
| 140 | // second = seconds of minute (0-60) | ||
| 141 | // Output: returns time encoded as fractional part of a day | ||
| 142 | // Purpose: encodes hour:minute:second to a DateTime value | ||
| 143 | |||
| 144 | { | ||
| 145 | int s; | ||
| 146 |
1/2✓ Branch 0 taken 248945 times.
✗ Branch 1 not taken.
|
248945 | if ((hour >= 0) |
| 147 |
1/2✓ Branch 0 taken 248945 times.
✗ Branch 1 not taken.
|
248945 | && (minute >= 0) |
| 148 |
1/2✓ Branch 0 taken 248945 times.
✗ Branch 1 not taken.
|
248945 | && (second >= 0)) |
| 149 | { | ||
| 150 | 248945 | s = (hour * 3600 + minute * 60 + second); | |
| 151 | 248945 | return (double)s/SecsPerDay; | |
| 152 | } | ||
| 153 | ✗ | else return 0.0; | |
| 154 | } | ||
| 155 | |||
| 156 | //============================================================================= | ||
| 157 | |||
| 158 | 3920831 | void datetime_decodeDate(DateTime date, int* year, int* month, int* day) | |
| 159 | |||
| 160 | // Input: date = encoded date/time value | ||
| 161 | // Output: year = 4-digit year | ||
| 162 | // month = month of year (1-12) | ||
| 163 | // day = day of month | ||
| 164 | // Purpose: decodes DateTime value to year-month-day. | ||
| 165 | |||
| 166 | { | ||
| 167 | int D1, D4, D100, D400; | ||
| 168 | int y, m, d, i, k, t; | ||
| 169 | |||
| 170 | 3920831 | D1 = 365; //365 | |
| 171 | 3920831 | D4 = D1 * 4 + 1; //1461 | |
| 172 | 3920831 | D100 = D4 * 25 - 1; //36524 | |
| 173 | 3920831 | D400 = D100 * 4 + 1; //146097 | |
| 174 | |||
| 175 | 3920831 | t = (int)(floor (date)) + DateDelta; | |
| 176 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3920831 times.
|
3920831 | if (t <= 0) |
| 177 | { | ||
| 178 | ✗ | *year = 0; | |
| 179 | ✗ | *month = 1; | |
| 180 | ✗ | *day = 1; | |
| 181 | } | ||
| 182 | else | ||
| 183 | { | ||
| 184 | 3920831 | t--; | |
| 185 | 3920831 | y = 1; | |
| 186 |
2/2✓ Branch 0 taken 19112532 times.
✓ Branch 1 taken 3920831 times.
|
23033363 | while (t >= D400) |
| 187 | { | ||
| 188 | 19112532 | t -= D400; | |
| 189 | 19112532 | y += 400; | |
| 190 | } | ||
| 191 | 3920831 | divMod(t, D100, &i, &d); | |
| 192 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3920831 times.
|
3920831 | if (i == 4) |
| 193 | { | ||
| 194 | ✗ | i--; | |
| 195 | ✗ | d += D100; | |
| 196 | } | ||
| 197 | 3920831 | y += i*100; | |
| 198 | 3920831 | divMod(d, D4, &i, &d); | |
| 199 | 3920831 | y += i*4; | |
| 200 | 3920831 | divMod(d, D1, &i, &d); | |
| 201 |
2/2✓ Branch 0 taken 1729 times.
✓ Branch 1 taken 3919102 times.
|
3920831 | if (i == 4) |
| 202 | { | ||
| 203 | 1729 | i--; | |
| 204 | 1729 | d += D1; | |
| 205 | } | ||
| 206 | 3920831 | y += i; | |
| 207 | 3920831 | k = isLeapYear(y); | |
| 208 | 3920831 | m = 1; | |
| 209 | for (;;) | ||
| 210 | { | ||
| 211 | 9790373 | i = DaysPerMonth[k][m-1]; | |
| 212 |
2/2✓ Branch 0 taken 3920831 times.
✓ Branch 1 taken 5869542 times.
|
9790373 | if (d < i) break; |
| 213 | 5869542 | d -= i; | |
| 214 | 5869542 | m++; | |
| 215 | } | ||
| 216 | 3920831 | *year = y; | |
| 217 | 3920831 | *month = m; | |
| 218 | 3920831 | *day = d + 1; | |
| 219 | } | ||
| 220 | 3920831 | } | |
| 221 | |||
| 222 | //============================================================================= | ||
| 223 | |||
| 224 | 4317778 | void datetime_decodeTime(DateTime time, int* h, int* m, int* s) | |
| 225 | |||
| 226 | // Input: time = decimal fraction of a day | ||
| 227 | // Output: h = hour of day (0-23) | ||
| 228 | // m = minute of hour (0-59) | ||
| 229 | // s = second of minute (0-59) | ||
| 230 | // Purpose: decodes DateTime value to hour:minute:second. | ||
| 231 | |||
| 232 | { | ||
| 233 | int secs; | ||
| 234 | int mins; | ||
| 235 | 4317778 | double fracDay = (time - floor(time)) * SecsPerDay; | |
| 236 | 4317778 | secs = (int)(floor(fracDay + 0.5)); | |
| 237 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4317778 times.
|
4317778 | if ( secs >= 86400 ) secs = 86399; |
| 238 | 4317778 | divMod(secs, 60, &mins, s); | |
| 239 | 4317778 | divMod(mins, 60, h, m); | |
| 240 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4317778 times.
|
4317778 | if ( *h > 23 ) *h = 0; |
| 241 | 4317778 | } | |
| 242 | |||
| 243 | //============================================================================= | ||
| 244 | |||
| 245 | 1879 | void datetime_dateToStr(DateTime date, char* s) | |
| 246 | |||
| 247 | // Input: date = encoded date/time value | ||
| 248 | // Output: s = formatted date string | ||
| 249 | // Purpose: represents DateTime date value as a formatted string. | ||
| 250 | |||
| 251 | { | ||
| 252 | int y, m, d; | ||
| 253 | 1879 | datetime_decodeDate(date, &y, &m, &d); | |
| 254 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 1879 times.
✗ Branch 2 not taken.
|
1879 | switch (DateFormat) |
| 255 | { | ||
| 256 | ✗ | case Y_M_D: | |
| 257 | ✗ | snprintf(s, DATE_STR_SIZE, "%4d-%3s-%02d", y, MonthTxt[m-1], d); | |
| 258 | ✗ | break; | |
| 259 | |||
| 260 | 1879 | case M_D_Y: | |
| 261 | //sprintf(dateStr, "%3s-%02d-%4d", MonthTxt[m-1], d, y); | ||
| 262 | 1879 | snprintf(s, DATE_STR_SIZE, "%02d/%02d/%04d", m, d, y); | |
| 263 | 1879 | break; | |
| 264 | |||
| 265 | ✗ | default: | |
| 266 | ✗ | snprintf(s, DATE_STR_SIZE, "%02d-%3s-%4d", d, MonthTxt[m-1], y); | |
| 267 | } | ||
| 268 | 1879 | } | |
| 269 | |||
| 270 | 2000 | void datetime_timeToStr(DateTime time, char* s) | |
| 271 | |||
| 272 | // Input: time = decimal fraction of a day | ||
| 273 | // Output: s = time in hr:min:sec format | ||
| 274 | // Purpose: represents DateTime time value as a formatted string. | ||
| 275 | |||
| 276 | { | ||
| 277 | int hr, min, sec; | ||
| 278 | 2000 | datetime_decodeTime(time, &hr, &min, &sec); | |
| 279 | 2000 | snprintf(s, TIME_STR_SIZE, "%02d:%02d:%02d", hr, min, sec); | |
| 280 | 2000 | } | |
| 281 | |||
| 282 | //============================================================================= | ||
| 283 | |||
| 284 | 168850 | int datetime_strToDate(char* s, DateTime* d) | |
| 285 | |||
| 286 | // Input: s = date as string | ||
| 287 | // Output: d = encoded date; | ||
| 288 | // returns 1 if conversion successful, 0 if not | ||
| 289 | // Purpose: converts string date s to DateTime value. | ||
| 290 | // | ||
| 291 | { | ||
| 292 | 168850 | int yr = 0, mon = 0, day = 0, n; | |
| 293 | char month[4]; | ||
| 294 | char sep1, sep2; | ||
| 295 | 168850 | *d = -DateDelta; | |
| 296 |
3/4✓ Branch 0 taken 168850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 168018 times.
✓ Branch 3 taken 832 times.
|
168850 | if (strchr(s, '-') || strchr(s, '/')) |
| 297 | { | ||
| 298 |
1/3✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 168018 times.
|
168018 | switch (DateFormat) |
| 299 | { | ||
| 300 | ✗ | case Y_M_D: | |
| 301 | ✗ | n = sscanf(s, "%d%c%d%c%d", &yr, &sep1, &mon, &sep2, &day); | |
| 302 | ✗ | if ( n < 3 ) | |
| 303 | { | ||
| 304 | ✗ | mon = 0; | |
| 305 | ✗ | n = sscanf(s, "%d%c%3s%c%d", &yr, &sep1, month, &sep2, &day); | |
| 306 | ✗ | if ( n < 3 ) return 0; | |
| 307 | } | ||
| 308 | ✗ | break; | |
| 309 | |||
| 310 | ✗ | case D_M_Y: | |
| 311 | ✗ | n = sscanf(s, "%d%c%d%c%d", &day, &sep1, &mon, &sep2, &yr); | |
| 312 | ✗ | if ( n < 3 ) | |
| 313 | { | ||
| 314 | ✗ | mon = 0; | |
| 315 | ✗ | n = sscanf(s, "%d%c%3s%c%d", &day, &sep1, month, &sep2, &yr); | |
| 316 | ✗ | if ( n < 3 ) return 0; | |
| 317 | } | ||
| 318 | ✗ | break; | |
| 319 | |||
| 320 | 168018 | default: // M_D_Y | |
| 321 | 168018 | n = sscanf(s, "%d%c%d%c%d", &mon, &sep1, &day, &sep2, &yr); | |
| 322 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 168018 times.
|
168018 | if ( n < 3 ) |
| 323 | { | ||
| 324 | ✗ | mon = 0; | |
| 325 | ✗ | n = sscanf(s, "%3s%c%d%c%d", month, &sep1, &day, &sep2, &yr); | |
| 326 | ✗ | if ( n < 3 ) return 0; | |
| 327 | } | ||
| 328 | } | ||
| 329 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 168018 times.
|
168018 | if (mon == 0) mon = datetime_findMonth(month); |
| 330 | 168018 | *d = datetime_encodeDate(yr, mon, day); | |
| 331 | } | ||
| 332 |
2/2✓ Branch 0 taken 832 times.
✓ Branch 1 taken 168018 times.
|
168850 | if (*d == -DateDelta) return 0; |
| 333 | 168018 | else return 1; | |
| 334 | } | ||
| 335 | |||
| 336 | //============================================================================= | ||
| 337 | |||
| 338 | 168898 | int datetime_strToTime(char* s, DateTime* t) | |
| 339 | |||
| 340 | // Input: s = time as string | ||
| 341 | // Output: t = encoded time, | ||
| 342 | // returns 1 if conversion successful, 0 if not | ||
| 343 | // Purpose: converts a string time to a DateTime value. | ||
| 344 | // Note: accepts time as hr:min:sec or as decimal hours. | ||
| 345 | |||
| 346 | { | ||
| 347 | 168898 | int n, hr, min = 0, sec = 0; | |
| 348 | char *endptr; | ||
| 349 | |||
| 350 | // Attempt to read time as decimal hours | ||
| 351 | 168898 | *t = strtod(s, &endptr); | |
| 352 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 168886 times.
|
168898 | if ( *endptr == 0 ) |
| 353 | { | ||
| 354 | 12 | *t /= 24.0; | |
| 355 | 12 | return 1; | |
| 356 | } | ||
| 357 | |||
| 358 | // Read time in hr:min:sec format | ||
| 359 | 168886 | *t = 0.0; | |
| 360 | 168886 | n = sscanf(s, "%d:%d:%d", &hr, &min, &sec); | |
| 361 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 168886 times.
|
168886 | if ( n == 0 ) return 0; |
| 362 | 168886 | *t = datetime_encodeTime(hr, min, sec); | |
| 363 |
3/6✓ Branch 0 taken 168886 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 168886 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 168886 times.
✗ Branch 5 not taken.
|
168886 | if ( (hr >= 0) && (min >= 0) && (sec >= 0) ) return 1; |
| 364 | ✗ | else return 0; | |
| 365 | } | ||
| 366 | |||
| 367 | //============================================================================= | ||
| 368 | |||
| 369 | 1786 | void datetime_setDateFormat(int fmt) | |
| 370 | |||
| 371 | // Input: fmt = date format code | ||
| 372 | // Output: none | ||
| 373 | // Purpose: sets date format | ||
| 374 | |||
| 375 | { | ||
| 376 |
2/4✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1786 times.
✗ Branch 3 not taken.
|
1786 | if ( fmt >= Y_M_D && fmt <= M_D_Y) DateFormat = fmt; |
| 377 | 1786 | } | |
| 378 | |||
| 379 | //============================================================================= | ||
| 380 | |||
| 381 | 3125468 | DateTime datetime_addSeconds(DateTime date1, double seconds) | |
| 382 | |||
| 383 | // Input: date1 = an encoded date/time value | ||
| 384 | // seconds = number of seconds to add to date1 | ||
| 385 | // Output: returns updated value of date1 | ||
| 386 | // Purpose: adds a given number of seconds to a date/time. | ||
| 387 | |||
| 388 | { | ||
| 389 | 3125468 | double d = floor(date1); | |
| 390 | int h, m, s; | ||
| 391 | 3125468 | datetime_decodeTime(date1, &h, &m, &s); | |
| 392 | 3125468 | return d + (3600.0*h + 60.0*m + s + seconds)/SecsPerDay; | |
| 393 | } | ||
| 394 | |||
| 395 | //============================================================================= | ||
| 396 | |||
| 397 | ✗ | DateTime datetime_addDays(DateTime date1, DateTime date2) | |
| 398 | |||
| 399 | // Input: date1 = an encoded date/time value | ||
| 400 | // date2 = decimal days to be added to date1 | ||
| 401 | // Output: returns date1 + date2 | ||
| 402 | // Purpose: adds a given number of decimal days to a date/time. | ||
| 403 | |||
| 404 | { | ||
| 405 | ✗ | double d1 = floor(date1); | |
| 406 | ✗ | double d2 = floor(date2); | |
| 407 | int h1, m1, s1; | ||
| 408 | int h2, m2, s2; | ||
| 409 | ✗ | datetime_decodeTime(date1, &h1, &m1, &s1); | |
| 410 | ✗ | datetime_decodeTime(date2, &h2, &m2, &s2); | |
| 411 | ✗ | return d1 + d2 + datetime_encodeTime(h1+h2, m1+m2, s1+s2); | |
| 412 | } | ||
| 413 | |||
| 414 | //============================================================================= | ||
| 415 | |||
| 416 | 66917 | long datetime_timeDiff(DateTime date1, DateTime date2) | |
| 417 | |||
| 418 | // Input: date1 = an encoded date/time value | ||
| 419 | // date2 = an encoded date/time value | ||
| 420 | // Output: returns date1 - date2 in seconds | ||
| 421 | // Purpose: finds number of seconds between two dates. | ||
| 422 | |||
| 423 | { | ||
| 424 | 66917 | double d1 = floor(date1); | |
| 425 | 66917 | double d2 = floor(date2); | |
| 426 | int h, m, s; | ||
| 427 | long s1, s2, secs; | ||
| 428 | 66917 | datetime_decodeTime(date1, &h, &m, &s); | |
| 429 | 66917 | s1 = 3600*h + 60*m + s; | |
| 430 | 66917 | datetime_decodeTime(date2, &h, &m, &s); | |
| 431 | 66917 | s2 = 3600*h + 60*m + s; | |
| 432 | 66917 | secs = (int)(floor((d1 - d2)*SecsPerDay + 0.5)); | |
| 433 | 66917 | secs += (s1 - s2); | |
| 434 | 66917 | return secs; | |
| 435 | } | ||
| 436 | |||
| 437 | //============================================================================= | ||
| 438 | |||
| 439 | 3199582 | int datetime_monthOfYear(DateTime date) | |
| 440 | |||
| 441 | // Input: date = an encoded date/time value | ||
| 442 | // Output: returns index of month of year (1..12) | ||
| 443 | // Purpose: finds month of year (Jan = 1 ...) for a given date. | ||
| 444 | |||
| 445 | { | ||
| 446 | int year, month, day; | ||
| 447 | 3199582 | datetime_decodeDate(date, &year, &month, &day); | |
| 448 | 3199582 | return month; | |
| 449 | } | ||
| 450 | |||
| 451 | //============================================================================= | ||
| 452 | |||
| 453 | 33222 | int datetime_dayOfYear(DateTime date) | |
| 454 | |||
| 455 | // Input: date = an encoded date/time value | ||
| 456 | // Output: returns day of year (1..365) | ||
| 457 | // Purpose: finds day of year (Jan 1 = 1) for a given date. | ||
| 458 | |||
| 459 | { | ||
| 460 | int year, month, day; | ||
| 461 | DateTime startOfYear; | ||
| 462 | 33222 | datetime_decodeDate(date, &year, &month, &day); | |
| 463 | 33222 | startOfYear = datetime_encodeDate(year, 1, 1); | |
| 464 | 33222 | return (int)(floor(date - startOfYear)) + 1; | |
| 465 | } | ||
| 466 | |||
| 467 | //============================================================================= | ||
| 468 | |||
| 469 | 1042780 | int datetime_dayOfWeek(DateTime date) | |
| 470 | |||
| 471 | // Input: date = an encoded date/time value | ||
| 472 | // Output: returns index of day of week (1..7) | ||
| 473 | // Purpose: finds day of week (Sun = 1, ... Sat = 7) for a given date. | ||
| 474 | |||
| 475 | { | ||
| 476 | 1042780 | int t = (int)(floor(date)) + DateDelta; | |
| 477 | 1042780 | return (t % 7) + 1; | |
| 478 | } | ||
| 479 | |||
| 480 | //============================================================================= | ||
| 481 | |||
| 482 | 1042780 | int datetime_hourOfDay(DateTime date) | |
| 483 | |||
| 484 | // Input: date = an encoded date/time value | ||
| 485 | // Output: returns hour of day (0..23) | ||
| 486 | // Purpose: finds hour of day (0 = 12 AM, ..., 23 = 11 PM) for a given date. | ||
| 487 | |||
| 488 | { | ||
| 489 | int hour, min, sec; | ||
| 490 | 1042780 | datetime_decodeTime(date, &hour, &min, &sec); | |
| 491 | 1042780 | return hour; | |
| 492 | } | ||
| 493 | |||
| 494 | //============================================================================= | ||
| 495 | |||
| 496 | 12 | int datetime_daysPerMonth(int year, int month) | |
| 497 | |||
| 498 | // Input: year = year in which month falls | ||
| 499 | // month = month of year (1..12) | ||
| 500 | // Output: returns number of days in the month | ||
| 501 | // Purpose: finds number of days in a given month of a specified year. | ||
| 502 | |||
| 503 | { | ||
| 504 |
2/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
|
12 | if ( month < 1 || month > 12 ) return 0; |
| 505 | 12 | return DaysPerMonth[isLeapYear(year)][month-1]; | |
| 506 | } | ||
| 507 | |||
| 508 | //============================================================================= | ||
| 509 | |||
| 510 | 1728 | void datetime_getTimeStamp(int fmt, DateTime aDate, int stampSize, char* timeStamp) | |
| 511 | |||
| 512 | // Input: fmt = desired date format code | ||
| 513 | // aDate = a date/time value in decimal days | ||
| 514 | // stampSize = the number of bytes allocated for the time stamp | ||
| 515 | // Output: returns a time stamp string (e.g., Year-Month-Day Hr:Min:Sec) | ||
| 516 | // Purpose: Expresses a decimal day date by a time stamp. | ||
| 517 | { | ||
| 518 | char dateStr[DATE_STR_SIZE]; | ||
| 519 | char timeStr[TIME_STR_SIZE]; | ||
| 520 | 1728 | int oldDateFormat = DateFormat; | |
| 521 | |||
| 522 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1728 times.
|
1728 | if ( stampSize < TIME_STAMP_SIZE ) return; |
| 523 | 1728 | datetime_setDateFormat(fmt); | |
| 524 | 1728 | datetime_dateToStr(aDate, dateStr); | |
| 525 | 1728 | DateFormat = oldDateFormat; | |
| 526 | 1728 | datetime_timeToStr(aDate, timeStr); | |
| 527 | 1728 | snprintf(timeStamp, stampSize, "%s %s", dateStr, timeStr); | |
| 528 | } | ||
| 529 |