A time interface class. This class replicates the normal time functions, but goes a couple of steps further. mbed library 82 and prior has a defective gmtime function. Also, this class enables access to setting the time, and adjusting the accuracy of the RTC.

Dependencies:   CalendarPage

Dependents:   CI-data-logger-server WattEye X10Svr SSDP_Server

Revision:
6:c79cfe750416
Parent:
5:a5f50b5fb856
Child:
7:1de342fa7840
--- a/TimeInterface.cpp	Thu Aug 06 11:13:47 2015 +0000
+++ b/TimeInterface.cpp	Thu Nov 26 16:32:36 2015 +0000
@@ -3,7 +3,7 @@
 
 #include "rtc_api.h"
 
-//#define DEBUG "Time"
+#define DEBUG "Time"
 #include <cstdio>
 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
 #define DBG(x, ...)  std::printf("[DBG %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
@@ -33,6 +33,8 @@
 
 TimeInterface::TimeInterface()
 {
+    dst = false;
+    memset(&dst_pair, 0, sizeof(dst_pair));  // that's enough to keep it from running
 }
 
 TimeInterface::~TimeInterface()
@@ -44,7 +46,7 @@
     NTPClient ntp;
     NTPResult res;
     // int16_t tzomin = get_tzo_min();
-    INFO("setTime(%s, %d, %d) %d\r\n", host, port, timeout, tzomin);
+    INFO("setTime(%s, %d, %d)\r\n", host, port, timeout);
     res = ntp.setTime(host, port, timeout);
     INFO("  ret: %d\r\n", res);
     if (res == NTP_OK) {
@@ -57,14 +59,66 @@
     return res;
 }
 
-void set_dst(bool dst)
+bool TimeInterface::parseDSTstring(TimeInterface::dst_event_t * result, const char * dstr)
 {
-    (void)dst;
+    int x;
+    dst_event_t test_dst;
+    
+    x = atoi(dstr);
+    if (x >= 1 && x <= 12) {
+        test_dst.MM = x;
+        dstr = strchr(dstr, '/');
+        if (dstr++) {
+            x = atoi(dstr);
+            if (x >= 1 && x <= 31) {
+                test_dst.DD = x;
+                dstr = strchr(dstr, ',');
+                if (dstr++) {
+                    x = atoi(dstr);
+                    if (x >= 0 && x <= 23) {
+                        test_dst.hh = x;
+                        dstr = strchr(dstr, ':');
+                        if (dstr++) {
+                            x = atoi(dstr);
+                            if (x >= 0 && x <= 59) {
+                                test_dst.mm = x;
+                                memcpy(result, &test_dst, sizeof(dst_event_t));
+                                INFO("parsed: %d/%d %d:%02d", test_dst.MM, test_dst.DD, test_dst.hh, test_dst.mm);
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return false;
 }
 
-bool get_dst(void)
+// parse MM/DD,hh:mm
+bool TimeInterface::set_dst(const char * dstStart, const char * dstStop)
 {
-    return false;   
+    dst_event_pair_t test_pair;
+    
+    if (parseDSTstring(&test_pair.dst_start, dstStart)
+    && parseDSTstring(&test_pair.dst_stop, dstStop)) {
+        memcpy(&dst_pair, &test_pair, sizeof(dst_event_pair_t));
+        INFO("set_dst from (%s,%s)", dstStart, dstStop);
+        return true;
+    }
+    WARN("failed to set_dst from (%s,%s)", dstStart, dstStop);
+    return false;
+}
+
+bool TimeInterface::set_dst(bool isdst)
+{
+    dst = isdst;
+    return true;
+}
+
+bool TimeInterface::get_dst(void)
+{
+    return dst;   
 }
 
 clock_t TimeInterface::clock(void)
@@ -77,9 +131,31 @@
     return std::time(timer);
 }
 
+uint32_t TimeInterface::minutesSinceJan(int mon, int day, int hr, int min)
+{
+    return (mon * 60 * 24 * 31) + (day * 60 * 24) + (hr * 60) + min;
+}
+
 time_t TimeInterface::timelocal(time_t* timer)
 {
-    return std::time(timer) + 60 * get_tzo_min();
+    time_t privTime;
+    struct tm * tminfo;
+    
+    if (dst_pair.dst_start.MM) {    // may have to change the dst
+        std::time(&privTime);
+        tminfo = std::localtime(&privTime);
+        
+        uint32_t min_since_jan = minutesSinceJan(tminfo->tm_mon + 1, tminfo->tm_mday, tminfo->tm_hour, tminfo->tm_min);
+        uint32_t min_dst_start = minutesSinceJan(dst_pair.dst_start.MM, dst_pair.dst_start.DD, dst_pair.dst_start.hh, dst_pair.dst_start.mm);
+        uint32_t min_dst_stop  = minutesSinceJan(dst_pair.dst_stop.MM, dst_pair.dst_stop.DD, dst_pair.dst_stop.hh, dst_pair.dst_stop.mm);
+        
+        if (min_since_jan >= min_dst_start && min_since_jan < min_dst_stop) {
+            dst = 1;
+        } else {
+            dst = 0;
+        }
+    }
+    return std::time(timer) + 60 * get_tzo_min() + 60 * dst;
 }
 
 char * TimeInterface::ctime(const time_t * timer)
@@ -118,7 +194,7 @@
 
 struct tm_ex * TimeInterface::gmtime(const time_t * timer)
 {
-    time_t priv = *timer + (get_tzo_min() * 60);
+    time_t priv = *timer + (get_tzo_min() * 60 + dst * 60);
     struct tm * tmp = std::localtime(&priv);
     
     tm_ext.tm_sec     = tmp->tm_sec;