Andrew Boyson
/
iot
Backing up an unused program in case of future need
Diff: time.cpp
- Revision:
- 8:45a0205a298f
- Parent:
- 7:024ace6d943c
--- a/time.cpp Thu Jun 02 09:26:28 2016 +0000 +++ b/time.cpp Thu Dec 06 11:40:19 2018 +0000 @@ -33,18 +33,14 @@ //Add a year at a time while there is more than a year of days left int year = 1970; //Unix epoch is 1970 int dayOfWeek = 4; //1 Jan 1970 is a Thursday - int dayOfYear; int leapYear; while(1) { //See if it is a leap year - int year4 = !(year % 4); - int year100 = !(year % 100); - int year400 = !(year % 400); - leapYear = false; - if (year4) leapYear = true; - if (year100) leapYear = false; - if (year400) leapYear = true; + leapYear = false; + if (year % 4 == 0) leapYear = true; + if (year % 100 == 0) leapYear = false; + if (year % 400 == 0) leapYear = true; //Find the number of days in this year int daysInYear = leapYear ? 366 : 365; @@ -61,30 +57,18 @@ year++; } - dayOfYear = daysLeft; + //Days left contains the days left from the start (1 Jan) of the current year + int dayOfYear = daysLeft + 1; dayOfWeek += daysLeft; dayOfWeek %= 7; //Add a month at a time while there is more than a month of days left - int month = 0; + static char monthlengths[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + int month = 1; while(1) { - int daysInMonth; - switch (month + 1) - { - case 1: daysInMonth = 31; break; - case 2: daysInMonth = leapYear ? 29 : 28; break; - case 3: daysInMonth = 31; break; - case 4: daysInMonth = 30; break; - case 5: daysInMonth = 31; break; - case 6: daysInMonth = 30; break; - case 7: daysInMonth = 31; break; - case 8: daysInMonth = 31; break; - case 9: daysInMonth = 30; break; - case 10: daysInMonth = 31; break; - case 11: daysInMonth = 30; break; - case 12: daysInMonth = 31; break; - } + int daysInMonth = monthlengths[month-1]; + if (month == 2 && leapYear) daysInMonth++; //Stop if this is the last month if (daysLeft < daysInMonth) break; @@ -93,15 +77,49 @@ daysLeft -= daysInMonth; month++; } - - ptm->tm_sec = seconds; - ptm->tm_min = minutes; - ptm->tm_hour = hours; - ptm->tm_mday = daysLeft + 1; - ptm->tm_mon = month; - ptm->tm_year = year - 1900; - ptm->tm_wday = dayOfWeek; - ptm->tm_yday = dayOfYear; + + //Days left contains the days left from the start (1st) of the current month + int dayOfMonth = daysLeft + 1; + + //Find the last Sunday in the month + int lastSunday = monthlengths[month-1]; + while (lastSunday > 0) + { + int weekday = (dayOfWeek + lastSunday - dayOfMonth) % 7; + if (weekday == 0) break; //Stop when weekday is Sunday + lastSunday--; + } + + //Work out if Daylight Saving Time applies + int dst; + if (month <= 2) dst = false; //Jan, Feb + if (month == 3) //Mar - DST true after 1am UTC on the last Sunday in March + { + if (dayOfMonth < lastSunday) dst = false; + if (dayOfMonth == lastSunday) dst = hours >= 1; + if (dayOfMonth > lastSunday) dst = true; + } + if (month >= 4 && month <= 9) dst = true; //Apr, May, Jun, Jul, Aug, Sep + if (month == 10) //Oct - DST false after 1am UTC on the last Sunday in October + { + if (dayOfMonth < lastSunday) dst = true; + if (dayOfMonth == lastSunday) dst = hours < 1; + if (dayOfMonth > lastSunday) dst = false; + } + if (month >= 11) dst = false; //Nov, Dec + + + //Set up the broken time TM structure + ptm->tm_sec = seconds; // 00 --> 59 + ptm->tm_min = minutes; // 00 --> 59 + ptm->tm_hour = hours; // 00 --> 23 + ptm->tm_mday = dayOfMonth; // 01 --> 31 + ptm->tm_mon = month - 1; // 00 --> 11 + ptm->tm_year = year - 1900; // Years since 1900 + ptm->tm_wday = dayOfWeek; // 0 --> 6 where 0 == Sunday + ptm->tm_yday = dayOfYear - 1; // 0 --> 365 + ptm->tm_isdst = dst; // +ve if DST, 0 if not DSTime, -ve if the information is not available. Note that 'true' evaluates to +1. + } void TimeGetTm(struct tm* ptm) {