This library takes the current time (which must be set to UTC, e.g. via an NTP call), and applies a timezone definition (loaded at startup) to calculate the local time. This includes the handling of daylight saving. See http://mbed.org/users/hlipka/notebook/time-zone-handling/ for more information (esp. how to get a time zone definition file).

Dependents:   CubiScan 000-FIN_youcef 005_ESSAI_youcef

Files at this revision

API Documentation at this revision

Comitter:
hlipka
Date:
Mon Jan 24 22:01:44 2011 +0000
Parent:
4:c84afcfbac84
Child:
6:f4693f2d03e6
Commit message:
bugfix: read time zones correctly when no current is set

Changed in this revision

Time.cpp Show annotated file Show diff for this revision Revisions of this file
Time.h Show annotated file Show diff for this revision Revisions of this file
--- a/Time.cpp	Fri Jan 21 23:05:05 2011 +0000
+++ b/Time.cpp	Mon Jan 24 22:01:44 2011 +0000
@@ -6,7 +6,7 @@
 using namespace std;
 
 class TimeZoneEntry {
-    public:
+public:
     TimeStamp *_from;
     TimeStamp *_to;
     int _offset;
@@ -15,8 +15,7 @@
 
 TimeZoneEntry* Time::_timeZoneEntries=NULL;
 
-bool TimeStamp::isSame(TimeStamp* ts)
-{
+bool TimeStamp::isSame(TimeStamp* ts) {
     if (ts->getYear()!=getYear())
         return false;
     if (ts->getMonth()!=getMonth())
@@ -29,8 +28,7 @@
         return false;
     return true;
 }
-bool TimeStamp::isBefore(TimeStamp* ts)
-{
+bool TimeStamp::isBefore(TimeStamp* ts) {
     if (getYear()<ts->getYear())
         return true;
     if (getYear()>ts->getYear())
@@ -53,11 +51,10 @@
 
     if (getSecond()<ts->getSecond())
         return true;
-    return false;        
+    return false;
 }
-bool TimeStamp::isAfter(TimeStamp* ts)
-{
-    return ts->isBefore(this);        
+bool TimeStamp::isAfter(TimeStamp* ts) {
+    return ts->isBefore(this);
 }
 
 Time::Time() {
@@ -82,68 +79,72 @@
         printf("error while reading timezone file [timezone.csv]\n");
         return;
     }
-    
+
     TimeZoneEntry *current=NULL;
 
 
     char tmp[128]; // enough for a single line
     while (fgets(tmp,sizeof(tmp),fp)!=0) {
-        int fyear, fmon, fday, fhour, fmin, fsec;
-        int tyear, tmon, tday, thour, tmin, tsec;
-        int offset;
-        int r=sscanf(tmp,"%4d-%2d-%2dT%2d:%2d:%2dZ,%4d-%2d-%2dT%2d:%2d:%2dZ,%d",
-                     &fyear, &fmon, &fday, &fhour, &fmin, &fsec,
-                     &tyear, &tmon, &tday, &thour, &tmin, &tsec,
-                     &offset
-                    );
-        if (13!=r)
-            continue;
-        if (tyear<currentYear || fyear>currentYear+4)
-            continue;
-            
-        TimeStamp *from=new TimeStamp(fyear, fmon, fday, fhour, fmin, fsec,0);
-        TimeStamp *to=new TimeStamp(tyear, tmon, tday, thour, tmin, tsec,0);
-        TimeZoneEntry *tze=new TimeZoneEntry();
-        tze->_from=from;
-        tze->_to=to;
-        tze->_offset=offset;
-        tze->next=NULL;
-        
-        if (NULL==current)
-        {
-            current=tze;
-            _timeZoneEntries=tze;
-        }
-        else
-        {
-            current->next=tze;
-            current=tze;
+        if (tmp[0]!='#') {
+            int fyear, fmon, fday, fhour, fmin, fsec;
+            int tyear, tmon, tday, thour, tmin, tsec;
+            int offset;
+            int r=sscanf(tmp,"%4d-%2d-%2dT%2d:%2d:%2dZ,%4d-%2d-%2dT%2d:%2d:%2dZ,%d",
+                         &fyear, &fmon, &fday, &fhour, &fmin, &fsec,
+                         &tyear, &tmon, &tday, &thour, &tmin, &tsec,
+                         &offset
+                        );
+            if (13!=r)
+                continue;
+            // when we have no current time, so the year is 1970 and we read everything
+            // otherwise skip everything more than 4 years in advance to save memory
+            if (currentYear!=1970 && (tyear<currentYear || fyear>currentYear+4)) {
+                continue;
+            }
+
+            TimeStamp *from=new TimeStamp(fyear, fmon, fday, fhour, fmin, fsec,0);
+            TimeStamp *to=new TimeStamp(tyear, tmon, tday, thour, tmin, tsec,0);
+            TimeZoneEntry *tze=new TimeZoneEntry();
+            tze->_from=from;
+            tze->_to=to;
+            tze->_offset=offset;
+            tze->next=NULL;
+
+            if (NULL==current) {
+                current=tze;
+                _timeZoneEntries=tze;
+            } else {
+                current->next=tze;
+                current=tze;
+            }
         }
     }
-    printf("closing time zone file\n");
+//    printf("closing time zone file\n");
     fclose(fp);
 }
 
 Time::~Time() {
 }
 
+int Time::getTimeOffset(TimeStamp* ts) {
+    TimeZoneEntry *current=_timeZoneEntries;
+
+    while (current!=NULL) {
+        if (current->_from->isBefore(ts) && current->_to->isAfter(ts)) {
+            return current->_offset;
+        }
+        current=current->next;
+    }
+    return 0;
+}
+
 TimeStamp* Time::getTime() {
     time_t rawtime;
     time ( &rawtime );
     TimeStamp *ts=new TimeStamp(rawtime);
-    
-    TimeZoneEntry *current=_timeZoneEntries;
-    
-    while (current!=NULL)
-    {
-        if (current->_from->isBefore(ts) && current->_to->isAfter(ts))
-        {
-            rawtime+=current->_offset;
-            ts->updateTime(rawtime);
-            break;
-        }
-        current=current->next;
-    }
-    
+
+    rawtime+=getTimeOffset(ts);
+    ts->updateTime(rawtime);
+
     return ts;
 }
--- a/Time.h	Fri Jan 21 23:05:05 2011 +0000
+++ b/Time.h	Mon Jan 24 22:01:44 2011 +0000
@@ -182,7 +182,8 @@
     long getUnixTime();
 private:
     static TimeZoneEntry* _timeZoneEntries;
-    void readTimeZones();
+    static void readTimeZones();
+    static int getTimeOffset(TimeStamp* ts);
 };
 
 #endif
\ No newline at end of file