Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
tm/tm.c@37:330b844f54b6, 2018-12-01 (annotated)
- Committer:
- andrewboyson
- Date:
- Sat Dec 01 19:13:29 2018 +0000
- Revision:
- 37:330b844f54b6
- Parent:
- 35:ba9f575aa3c6
- Child:
- 38:25b2a3c494aa
Modified to remove dependence on time_t (32bit) and used an int64 instead.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 37:330b844f54b6 | 1 | #include <time.h> |
andrewboyson | 26:0421132e6eaf | 2 | #include <stdlib.h> |
andrewboyson | 26:0421132e6eaf | 3 | #include <stdio.h> |
andrewboyson | 26:0421132e6eaf | 4 | #include <string.h> |
andrewboyson | 26:0421132e6eaf | 5 | #include <stdbool.h> |
andrewboyson | 37:330b844f54b6 | 6 | #include <stdint.h> |
andrewboyson | 26:0421132e6eaf | 7 | |
andrewboyson | 26:0421132e6eaf | 8 | #define STD_OFFSET 0 |
andrewboyson | 26:0421132e6eaf | 9 | #define DST_OFFSET 1 |
andrewboyson | 26:0421132e6eaf | 10 | |
andrewboyson | 37:330b844f54b6 | 11 | |
andrewboyson | 26:0421132e6eaf | 12 | static bool isLeapYear(int year) |
andrewboyson | 26:0421132e6eaf | 13 | { |
andrewboyson | 26:0421132e6eaf | 14 | year += 1900; |
andrewboyson | 26:0421132e6eaf | 15 | bool leapYear = !(year & 0x3); |
andrewboyson | 26:0421132e6eaf | 16 | if (year >= 2100) |
andrewboyson | 26:0421132e6eaf | 17 | { |
andrewboyson | 26:0421132e6eaf | 18 | if (year % 100 == 0) leapYear = false; |
andrewboyson | 26:0421132e6eaf | 19 | if (year % 400 == 0) leapYear = true; |
andrewboyson | 26:0421132e6eaf | 20 | } |
andrewboyson | 26:0421132e6eaf | 21 | return leapYear; |
andrewboyson | 26:0421132e6eaf | 22 | |
andrewboyson | 26:0421132e6eaf | 23 | } |
andrewboyson | 26:0421132e6eaf | 24 | static int monthLength(int year, int month) |
andrewboyson | 26:0421132e6eaf | 25 | { |
andrewboyson | 26:0421132e6eaf | 26 | static char monthlengths[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
andrewboyson | 26:0421132e6eaf | 27 | int daysInMonth = monthlengths[month]; |
andrewboyson | 26:0421132e6eaf | 28 | if (month == 1 && isLeapYear(year)) daysInMonth++; //February is month 1 of months 0 to 11 |
andrewboyson | 26:0421132e6eaf | 29 | return daysInMonth; |
andrewboyson | 26:0421132e6eaf | 30 | } |
andrewboyson | 26:0421132e6eaf | 31 | static bool isDst(int year, int month, int dayOfMonth, int dayOfWeek, int hours) |
andrewboyson | 26:0421132e6eaf | 32 | { |
andrewboyson | 26:0421132e6eaf | 33 | //Find the last Sunday in the month |
andrewboyson | 26:0421132e6eaf | 34 | int lastDayOfMonth = monthLength(year, month); |
andrewboyson | 26:0421132e6eaf | 35 | int daysToEndOfMonth = lastDayOfMonth - dayOfMonth; |
andrewboyson | 26:0421132e6eaf | 36 | int dayOfWeekOfLastDayOfMonth = (dayOfWeek + daysToEndOfMonth) % 7; |
andrewboyson | 26:0421132e6eaf | 37 | int lastSundayDayOfMonth = lastDayOfMonth - dayOfWeekOfLastDayOfMonth; |
andrewboyson | 26:0421132e6eaf | 38 | |
andrewboyson | 26:0421132e6eaf | 39 | //Check each month |
andrewboyson | 26:0421132e6eaf | 40 | if (month <= 1) return false; //Jan, Feb |
andrewboyson | 26:0421132e6eaf | 41 | if (month == 2) //Mar - DST true after 1am UTC on the last Sunday in March |
andrewboyson | 26:0421132e6eaf | 42 | { |
andrewboyson | 26:0421132e6eaf | 43 | if (dayOfMonth < lastSundayDayOfMonth) return false; |
andrewboyson | 26:0421132e6eaf | 44 | if (dayOfMonth == lastSundayDayOfMonth) return hours >= 1; |
andrewboyson | 26:0421132e6eaf | 45 | if (dayOfMonth > lastSundayDayOfMonth) return true; |
andrewboyson | 26:0421132e6eaf | 46 | } |
andrewboyson | 26:0421132e6eaf | 47 | if (month >= 3 && month <= 8) return true; //Apr, May, Jun, Jul, Aug, Sep |
andrewboyson | 26:0421132e6eaf | 48 | if (month == 9) //Oct - DST false after 1am UTC on the last Sunday in October |
andrewboyson | 26:0421132e6eaf | 49 | { |
andrewboyson | 26:0421132e6eaf | 50 | if (dayOfMonth < lastSundayDayOfMonth) return true; |
andrewboyson | 26:0421132e6eaf | 51 | if (dayOfMonth == lastSundayDayOfMonth) return hours < 1; |
andrewboyson | 26:0421132e6eaf | 52 | if (dayOfMonth > lastSundayDayOfMonth) return false; |
andrewboyson | 26:0421132e6eaf | 53 | } |
andrewboyson | 26:0421132e6eaf | 54 | if (month >= 10) return false; //Nov, Dec |
andrewboyson | 26:0421132e6eaf | 55 | return false; |
andrewboyson | 26:0421132e6eaf | 56 | } |
andrewboyson | 26:0421132e6eaf | 57 | static void calculateDayOfYearAndWeek(int thisYear, int thisMonth, int thisMonthDay, int* pDayOfYear, int* pDayOfWeek) |
andrewboyson | 26:0421132e6eaf | 58 | { |
andrewboyson | 26:0421132e6eaf | 59 | int dayOfYear = 0; //1 Jan is day 0 |
andrewboyson | 26:0421132e6eaf | 60 | int dayOfWeek = 4; //1 Jan 1970 is a Thursday |
andrewboyson | 26:0421132e6eaf | 61 | |
andrewboyson | 26:0421132e6eaf | 62 | //Add days of each whole year |
andrewboyson | 26:0421132e6eaf | 63 | for (int y = 70; y < thisYear; y++) |
andrewboyson | 26:0421132e6eaf | 64 | { |
andrewboyson | 26:0421132e6eaf | 65 | int lengthOfYear = isLeapYear(y) ? 366 : 365; |
andrewboyson | 26:0421132e6eaf | 66 | dayOfWeek += lengthOfYear; |
andrewboyson | 26:0421132e6eaf | 67 | } |
andrewboyson | 26:0421132e6eaf | 68 | |
andrewboyson | 26:0421132e6eaf | 69 | //Add days of each whole month |
andrewboyson | 26:0421132e6eaf | 70 | for (int m = 0; m < thisMonth; m++) |
andrewboyson | 26:0421132e6eaf | 71 | { |
andrewboyson | 26:0421132e6eaf | 72 | int lengthOfMonth = monthLength(thisYear, m); |
andrewboyson | 26:0421132e6eaf | 73 | dayOfYear += lengthOfMonth; |
andrewboyson | 26:0421132e6eaf | 74 | dayOfWeek += lengthOfMonth; |
andrewboyson | 26:0421132e6eaf | 75 | } |
andrewboyson | 26:0421132e6eaf | 76 | |
andrewboyson | 26:0421132e6eaf | 77 | //Add days of part month |
andrewboyson | 26:0421132e6eaf | 78 | thisMonthDay--; //thisMonthDay is 01 to 31 where we need 00 to 30 |
andrewboyson | 26:0421132e6eaf | 79 | dayOfYear += thisMonthDay; |
andrewboyson | 26:0421132e6eaf | 80 | dayOfWeek += thisMonthDay; |
andrewboyson | 26:0421132e6eaf | 81 | |
andrewboyson | 26:0421132e6eaf | 82 | //Update the day of year and day of week parts of the struct tm |
andrewboyson | 26:0421132e6eaf | 83 | *pDayOfYear = dayOfYear; // 0 --> 365 |
andrewboyson | 26:0421132e6eaf | 84 | *pDayOfWeek = dayOfWeek % 7; // 0 --> 6 |
andrewboyson | 26:0421132e6eaf | 85 | } |
andrewboyson | 26:0421132e6eaf | 86 | static void normalise(int* pHours, int* pDayOfWeek, int* pDayOfMonth, int* pMonth, int * pDayOfYear, int* pYear) |
andrewboyson | 26:0421132e6eaf | 87 | { |
andrewboyson | 26:0421132e6eaf | 88 | if (*pHours > 23) |
andrewboyson | 26:0421132e6eaf | 89 | { |
andrewboyson | 26:0421132e6eaf | 90 | *pHours -= 24; |
andrewboyson | 26:0421132e6eaf | 91 | ++*pDayOfWeek; |
andrewboyson | 26:0421132e6eaf | 92 | if (*pDayOfWeek > 6) *pDayOfWeek = 0; |
andrewboyson | 26:0421132e6eaf | 93 | ++*pDayOfYear; |
andrewboyson | 26:0421132e6eaf | 94 | ++*pDayOfMonth; |
andrewboyson | 26:0421132e6eaf | 95 | if (*pDayOfMonth > monthLength(*pYear, *pMonth)) |
andrewboyson | 26:0421132e6eaf | 96 | { |
andrewboyson | 26:0421132e6eaf | 97 | ++*pMonth; |
andrewboyson | 26:0421132e6eaf | 98 | if (*pMonth > 11) |
andrewboyson | 26:0421132e6eaf | 99 | { |
andrewboyson | 26:0421132e6eaf | 100 | ++*pYear; |
andrewboyson | 26:0421132e6eaf | 101 | *pDayOfYear = 0; |
andrewboyson | 26:0421132e6eaf | 102 | *pMonth = 0; |
andrewboyson | 26:0421132e6eaf | 103 | } |
andrewboyson | 26:0421132e6eaf | 104 | *pDayOfMonth = 1; |
andrewboyson | 26:0421132e6eaf | 105 | } |
andrewboyson | 26:0421132e6eaf | 106 | } |
andrewboyson | 26:0421132e6eaf | 107 | |
andrewboyson | 26:0421132e6eaf | 108 | if (*pHours < 0) |
andrewboyson | 26:0421132e6eaf | 109 | { |
andrewboyson | 26:0421132e6eaf | 110 | *pHours += 24; |
andrewboyson | 26:0421132e6eaf | 111 | --*pDayOfWeek; |
andrewboyson | 26:0421132e6eaf | 112 | if (*pDayOfWeek < 0) *pDayOfWeek = 6; |
andrewboyson | 26:0421132e6eaf | 113 | --*pDayOfYear; |
andrewboyson | 26:0421132e6eaf | 114 | --*pDayOfMonth; |
andrewboyson | 26:0421132e6eaf | 115 | if (*pDayOfMonth < 1) |
andrewboyson | 26:0421132e6eaf | 116 | { |
andrewboyson | 26:0421132e6eaf | 117 | --*pMonth; |
andrewboyson | 26:0421132e6eaf | 118 | if (*pMonth < 0) |
andrewboyson | 26:0421132e6eaf | 119 | { |
andrewboyson | 26:0421132e6eaf | 120 | --*pYear; |
andrewboyson | 26:0421132e6eaf | 121 | *pDayOfYear = isLeapYear(*pYear) ? 365 : 364; |
andrewboyson | 26:0421132e6eaf | 122 | *pMonth = 11; |
andrewboyson | 26:0421132e6eaf | 123 | } |
andrewboyson | 26:0421132e6eaf | 124 | *pDayOfMonth = monthLength(*pYear, *pMonth); |
andrewboyson | 26:0421132e6eaf | 125 | } |
andrewboyson | 26:0421132e6eaf | 126 | } |
andrewboyson | 26:0421132e6eaf | 127 | } |
andrewboyson | 26:0421132e6eaf | 128 | static void addYears(int* pYear, int* pDayOfWeek, int* pDaysLeft) |
andrewboyson | 26:0421132e6eaf | 129 | { |
andrewboyson | 26:0421132e6eaf | 130 | while(1) |
andrewboyson | 26:0421132e6eaf | 131 | { |
andrewboyson | 26:0421132e6eaf | 132 | //See if it is a leap year |
andrewboyson | 26:0421132e6eaf | 133 | int leapYear = isLeapYear(*pYear); |
andrewboyson | 26:0421132e6eaf | 134 | |
andrewboyson | 26:0421132e6eaf | 135 | //Find the number of days in this year |
andrewboyson | 26:0421132e6eaf | 136 | int daysInYear = leapYear ? 366 : 365; |
andrewboyson | 26:0421132e6eaf | 137 | |
andrewboyson | 26:0421132e6eaf | 138 | //Stop if this is the final year |
andrewboyson | 26:0421132e6eaf | 139 | if (*pDaysLeft < daysInYear) break; |
andrewboyson | 26:0421132e6eaf | 140 | |
andrewboyson | 26:0421132e6eaf | 141 | //Calculate the current day of the week at the start of the year |
andrewboyson | 26:0421132e6eaf | 142 | *pDayOfWeek += leapYear ? 2 : 1; |
andrewboyson | 26:0421132e6eaf | 143 | if (*pDayOfWeek >= 7) *pDayOfWeek -= 7; |
andrewboyson | 26:0421132e6eaf | 144 | |
andrewboyson | 26:0421132e6eaf | 145 | //Move on to the next year |
andrewboyson | 26:0421132e6eaf | 146 | *pDaysLeft -= daysInYear; |
andrewboyson | 26:0421132e6eaf | 147 | ++*pYear; |
andrewboyson | 26:0421132e6eaf | 148 | } |
andrewboyson | 26:0421132e6eaf | 149 | } |
andrewboyson | 26:0421132e6eaf | 150 | static void addMonths(int year, int* pMonth, int* pDaysLeft) |
andrewboyson | 26:0421132e6eaf | 151 | { |
andrewboyson | 26:0421132e6eaf | 152 | while(1) |
andrewboyson | 26:0421132e6eaf | 153 | { |
andrewboyson | 26:0421132e6eaf | 154 | int daysInMonth = monthLength(year, *pMonth); |
andrewboyson | 26:0421132e6eaf | 155 | |
andrewboyson | 26:0421132e6eaf | 156 | //Stop if this is the last month |
andrewboyson | 26:0421132e6eaf | 157 | if (*pDaysLeft < daysInMonth) break; |
andrewboyson | 26:0421132e6eaf | 158 | |
andrewboyson | 26:0421132e6eaf | 159 | //Move onto next month |
andrewboyson | 26:0421132e6eaf | 160 | *pDaysLeft -= daysInMonth; |
andrewboyson | 26:0421132e6eaf | 161 | ++*pMonth; |
andrewboyson | 26:0421132e6eaf | 162 | } |
andrewboyson | 26:0421132e6eaf | 163 | } |
andrewboyson | 37:330b844f54b6 | 164 | static void timeToTm(int64_t t, struct tm* ptm, bool local) |
andrewboyson | 26:0421132e6eaf | 165 | { |
andrewboyson | 26:0421132e6eaf | 166 | //Extract the seconds, minutes, hours and days from the time_t t |
andrewboyson | 26:0421132e6eaf | 167 | div_t divres; |
andrewboyson | 26:0421132e6eaf | 168 | divres = div( t, 60); int seconds = divres.rem; |
andrewboyson | 26:0421132e6eaf | 169 | divres = div(divres.quot, 60); int minutes = divres.rem; |
andrewboyson | 26:0421132e6eaf | 170 | divres = div(divres.quot, 24); int hours = divres.rem; |
andrewboyson | 26:0421132e6eaf | 171 | int daysLeft = divres.quot; |
andrewboyson | 26:0421132e6eaf | 172 | |
andrewboyson | 26:0421132e6eaf | 173 | //Add a year at a time while there is more than a year of days left |
andrewboyson | 26:0421132e6eaf | 174 | int year = 70; //Unix epoch is 1970 |
andrewboyson | 26:0421132e6eaf | 175 | int dayOfWeek = 4; //1 Jan 1970 is a Thursday |
andrewboyson | 26:0421132e6eaf | 176 | addYears(&year, &dayOfWeek, &daysLeft); |
andrewboyson | 26:0421132e6eaf | 177 | |
andrewboyson | 26:0421132e6eaf | 178 | //Days left contains the days left from the start (1 Jan) of the current year |
andrewboyson | 26:0421132e6eaf | 179 | int dayOfYear = daysLeft; |
andrewboyson | 26:0421132e6eaf | 180 | dayOfWeek += daysLeft; |
andrewboyson | 26:0421132e6eaf | 181 | dayOfWeek %= 7; |
andrewboyson | 26:0421132e6eaf | 182 | |
andrewboyson | 26:0421132e6eaf | 183 | //Add a month at a time while there is more than a month of days left |
andrewboyson | 26:0421132e6eaf | 184 | int month = 0; |
andrewboyson | 26:0421132e6eaf | 185 | addMonths(year, &month, &daysLeft); |
andrewboyson | 26:0421132e6eaf | 186 | |
andrewboyson | 26:0421132e6eaf | 187 | //Days left contains the days left from the start (1st) of the current month |
andrewboyson | 26:0421132e6eaf | 188 | int dayOfMonth = daysLeft + 1; |
andrewboyson | 26:0421132e6eaf | 189 | |
andrewboyson | 26:0421132e6eaf | 190 | //Deal with local time offsets |
andrewboyson | 26:0421132e6eaf | 191 | int dst; |
andrewboyson | 26:0421132e6eaf | 192 | if (local) |
andrewboyson | 26:0421132e6eaf | 193 | { |
andrewboyson | 26:0421132e6eaf | 194 | //Work out if Daylight Saving Time applies |
andrewboyson | 26:0421132e6eaf | 195 | dst = isDst(year, month, dayOfMonth, dayOfWeek, hours); |
andrewboyson | 26:0421132e6eaf | 196 | |
andrewboyson | 26:0421132e6eaf | 197 | //Adjust for the timezone |
andrewboyson | 26:0421132e6eaf | 198 | hours += dst ? DST_OFFSET : STD_OFFSET; |
andrewboyson | 26:0421132e6eaf | 199 | normalise(&hours, &dayOfWeek, &dayOfMonth, &month, &dayOfYear, &year); |
andrewboyson | 26:0421132e6eaf | 200 | } |
andrewboyson | 26:0421132e6eaf | 201 | else |
andrewboyson | 26:0421132e6eaf | 202 | { |
andrewboyson | 26:0421132e6eaf | 203 | dst = -1; |
andrewboyson | 26:0421132e6eaf | 204 | } |
andrewboyson | 26:0421132e6eaf | 205 | |
andrewboyson | 26:0421132e6eaf | 206 | //Set up the broken time TM structure |
andrewboyson | 26:0421132e6eaf | 207 | ptm->tm_sec = seconds; // 00 --> 59 |
andrewboyson | 26:0421132e6eaf | 208 | ptm->tm_min = minutes; // 00 --> 59 |
andrewboyson | 26:0421132e6eaf | 209 | ptm->tm_hour = hours; // 00 --> 23 |
andrewboyson | 26:0421132e6eaf | 210 | ptm->tm_mday = dayOfMonth; // 01 --> 31 |
andrewboyson | 26:0421132e6eaf | 211 | ptm->tm_mon = month; // 00 --> 11 |
andrewboyson | 26:0421132e6eaf | 212 | ptm->tm_year = year; // Years since 1900 |
andrewboyson | 26:0421132e6eaf | 213 | ptm->tm_wday = dayOfWeek; // 0 --> 6 where 0 == Sunday |
andrewboyson | 26:0421132e6eaf | 214 | ptm->tm_yday = dayOfYear; // 0 --> 365 |
andrewboyson | 26:0421132e6eaf | 215 | ptm->tm_isdst = dst; // +ve if DST, 0 if not DSTime, -ve if the information is not available. Note that 'true' evaluates to +1. |
andrewboyson | 26:0421132e6eaf | 216 | } |
andrewboyson | 37:330b844f54b6 | 217 | |
andrewboyson | 37:330b844f54b6 | 218 | |
andrewboyson | 37:330b844f54b6 | 219 | void TmUtcFromSeconds1970(int64_t time, struct tm* ptm) |
andrewboyson | 26:0421132e6eaf | 220 | { |
andrewboyson | 26:0421132e6eaf | 221 | timeToTm(time, ptm, false); |
andrewboyson | 26:0421132e6eaf | 222 | } |
andrewboyson | 37:330b844f54b6 | 223 | void TmLocalFromSeconds1970(int64_t time, struct tm* ptm) |
andrewboyson | 26:0421132e6eaf | 224 | { |
andrewboyson | 26:0421132e6eaf | 225 | timeToTm(time, ptm, true); |
andrewboyson | 26:0421132e6eaf | 226 | } |
andrewboyson | 37:330b844f54b6 | 227 | int64_t TmUtcToSeconds1970(struct tm* ptm) |
andrewboyson | 26:0421132e6eaf | 228 | { |
andrewboyson | 37:330b844f54b6 | 229 | int64_t days = 0; |
andrewboyson | 26:0421132e6eaf | 230 | |
andrewboyson | 26:0421132e6eaf | 231 | for (int y = 70; y < ptm->tm_year; y++) days += isLeapYear(y) ? 366 : 365; |
andrewboyson | 26:0421132e6eaf | 232 | |
andrewboyson | 26:0421132e6eaf | 233 | days += ptm->tm_yday; |
andrewboyson | 26:0421132e6eaf | 234 | |
andrewboyson | 26:0421132e6eaf | 235 | return days * 86400 + |
andrewboyson | 26:0421132e6eaf | 236 | ptm->tm_hour * 3600 + |
andrewboyson | 26:0421132e6eaf | 237 | ptm->tm_min * 60 + |
andrewboyson | 26:0421132e6eaf | 238 | ptm->tm_sec; |
andrewboyson | 26:0421132e6eaf | 239 | } |
andrewboyson | 37:330b844f54b6 | 240 | |
andrewboyson | 37:330b844f54b6 | 241 | |
andrewboyson | 31:f6ff7fdb9c67 | 242 | int TmSecondsBetween(struct tm* ptmLater, struct tm* ptmEarlier) |
andrewboyson | 26:0421132e6eaf | 243 | { |
andrewboyson | 26:0421132e6eaf | 244 | int days = 0; |
andrewboyson | 26:0421132e6eaf | 245 | |
andrewboyson | 26:0421132e6eaf | 246 | if (ptmLater->tm_year > ptmEarlier->tm_year) for (int y = ptmEarlier->tm_year; y < ptmLater->tm_year; y++) days += isLeapYear(y) ? 366 : 365; |
andrewboyson | 26:0421132e6eaf | 247 | else for (int y = ptmEarlier->tm_year; y > ptmLater->tm_year; y--) days -= isLeapYear(y) ? 366 : 365; |
andrewboyson | 26:0421132e6eaf | 248 | |
andrewboyson | 26:0421132e6eaf | 249 | days += ptmLater->tm_yday - ptmEarlier->tm_yday; |
andrewboyson | 26:0421132e6eaf | 250 | |
andrewboyson | 26:0421132e6eaf | 251 | return days * 86400 + |
andrewboyson | 26:0421132e6eaf | 252 | (ptmLater->tm_hour - ptmEarlier->tm_hour) * 3600 + |
andrewboyson | 26:0421132e6eaf | 253 | (ptmLater->tm_min - ptmEarlier->tm_min ) * 60 + |
andrewboyson | 26:0421132e6eaf | 254 | (ptmLater->tm_sec - ptmEarlier->tm_sec ); |
andrewboyson | 26:0421132e6eaf | 255 | } |
andrewboyson | 26:0421132e6eaf | 256 | |
andrewboyson | 31:f6ff7fdb9c67 | 257 | void TmUtcToLocal(struct tm* ptm) |
andrewboyson | 26:0421132e6eaf | 258 | { |
andrewboyson | 26:0421132e6eaf | 259 | //Establish DST |
andrewboyson | 26:0421132e6eaf | 260 | ptm->tm_isdst = isDst(ptm->tm_year, ptm->tm_mon, ptm->tm_mday, ptm->tm_wday, ptm->tm_hour); |
andrewboyson | 26:0421132e6eaf | 261 | |
andrewboyson | 26:0421132e6eaf | 262 | //Adjust for the timezone |
andrewboyson | 26:0421132e6eaf | 263 | ptm->tm_hour += ptm->tm_isdst ? DST_OFFSET : STD_OFFSET; |
andrewboyson | 26:0421132e6eaf | 264 | normalise(&ptm->tm_hour, &ptm->tm_wday, &ptm->tm_mday, &ptm->tm_mon, &ptm->tm_yday, &ptm->tm_year); |
andrewboyson | 26:0421132e6eaf | 265 | } |
andrewboyson | 26:0421132e6eaf | 266 | |
andrewboyson | 31:f6ff7fdb9c67 | 267 | void TmFromAsciiDateTime(const char* pDate, const char* pTime, struct tm* ptm) // Convert compile time to system time |
andrewboyson | 26:0421132e6eaf | 268 | { |
andrewboyson | 26:0421132e6eaf | 269 | //__DATE__ The string constant contains eleven characters and looks like "Feb 12 1996". If the day of the month is less than 10, it is padded with a space on the left. |
andrewboyson | 26:0421132e6eaf | 270 | char month[5]; |
andrewboyson | 26:0421132e6eaf | 271 | sscanf(pDate, "%s %d %d", month, &ptm->tm_mday, &ptm->tm_year); ptm->tm_year -= 1900; |
andrewboyson | 26:0421132e6eaf | 272 | |
andrewboyson | 26:0421132e6eaf | 273 | // Find where month is in month_names. Deduce month value. |
andrewboyson | 26:0421132e6eaf | 274 | static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; |
andrewboyson | 26:0421132e6eaf | 275 | ptm->tm_mon = (strstr(month_names, month) - month_names) / 3; |
andrewboyson | 26:0421132e6eaf | 276 | |
andrewboyson | 26:0421132e6eaf | 277 | //__TIME__ The string constant contains eight characters and looks like "23:59:01". |
andrewboyson | 26:0421132e6eaf | 278 | sscanf(pTime, "%2d %*c %2d %*c %2d", &ptm->tm_hour, &ptm->tm_min, &ptm->tm_sec); |
andrewboyson | 26:0421132e6eaf | 279 | |
andrewboyson | 26:0421132e6eaf | 280 | //Fill the day of week and the day of year part of the tm structure |
andrewboyson | 26:0421132e6eaf | 281 | calculateDayOfYearAndWeek(ptm->tm_year, ptm->tm_mon, ptm->tm_mday, &ptm->tm_yday, &ptm->tm_wday); |
andrewboyson | 26:0421132e6eaf | 282 | } |
andrewboyson | 37:330b844f54b6 | 283 | void TmIncrement(struct tm* ptm) |
andrewboyson | 37:330b844f54b6 | 284 | { |
andrewboyson | 37:330b844f54b6 | 285 | ptm->tm_sec++; |
andrewboyson | 37:330b844f54b6 | 286 | if (ptm->tm_sec > 59) |
andrewboyson | 37:330b844f54b6 | 287 | { |
andrewboyson | 37:330b844f54b6 | 288 | ptm->tm_sec = 0; |
andrewboyson | 37:330b844f54b6 | 289 | ptm->tm_min++; |
andrewboyson | 37:330b844f54b6 | 290 | } |
andrewboyson | 37:330b844f54b6 | 291 | if (ptm->tm_min > 59) |
andrewboyson | 37:330b844f54b6 | 292 | { |
andrewboyson | 37:330b844f54b6 | 293 | ptm->tm_min = 0; |
andrewboyson | 37:330b844f54b6 | 294 | ptm->tm_hour++; |
andrewboyson | 37:330b844f54b6 | 295 | } |
andrewboyson | 37:330b844f54b6 | 296 | if (ptm->tm_hour > 23) |
andrewboyson | 37:330b844f54b6 | 297 | { |
andrewboyson | 37:330b844f54b6 | 298 | ptm->tm_hour = 0; |
andrewboyson | 37:330b844f54b6 | 299 | ptm->tm_wday++; |
andrewboyson | 37:330b844f54b6 | 300 | if (ptm->tm_wday > 6) ptm->tm_wday = 0; |
andrewboyson | 37:330b844f54b6 | 301 | ptm->tm_yday++; |
andrewboyson | 37:330b844f54b6 | 302 | ptm->tm_mday++; |
andrewboyson | 37:330b844f54b6 | 303 | if (ptm->tm_mday > monthLength(ptm->tm_year, ptm->tm_mon)) |
andrewboyson | 37:330b844f54b6 | 304 | { |
andrewboyson | 37:330b844f54b6 | 305 | ptm->tm_mon++; |
andrewboyson | 37:330b844f54b6 | 306 | if (ptm->tm_mon > 11) |
andrewboyson | 37:330b844f54b6 | 307 | { |
andrewboyson | 37:330b844f54b6 | 308 | ptm->tm_year++; |
andrewboyson | 37:330b844f54b6 | 309 | ptm->tm_yday = 0; |
andrewboyson | 37:330b844f54b6 | 310 | ptm->tm_mon = 0; |
andrewboyson | 37:330b844f54b6 | 311 | } |
andrewboyson | 37:330b844f54b6 | 312 | ptm->tm_mday = 1; |
andrewboyson | 37:330b844f54b6 | 313 | } |
andrewboyson | 37:330b844f54b6 | 314 | } |
andrewboyson | 37:330b844f54b6 | 315 | } |