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

Committer:
hlipka
Date:
Mon Jan 24 22:01:44 2011 +0000
Revision:
5:fde01b92a384
Parent:
4:c84afcfbac84
Child:
7:0c7207d674d3
bugfix: read time zones correctly when no current is set

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hlipka 0:ab93db24fcc8 1 #include "Time.h"
hlipka 0:ab93db24fcc8 2
hlipka 0:ab93db24fcc8 3 #include "stdio.h"
hlipka 0:ab93db24fcc8 4 #include "time.h"
hlipka 0:ab93db24fcc8 5
hlipka 0:ab93db24fcc8 6 using namespace std;
hlipka 0:ab93db24fcc8 7
hlipka 0:ab93db24fcc8 8 class TimeZoneEntry {
hlipka 5:fde01b92a384 9 public:
hlipka 0:ab93db24fcc8 10 TimeStamp *_from;
hlipka 0:ab93db24fcc8 11 TimeStamp *_to;
hlipka 0:ab93db24fcc8 12 int _offset;
hlipka 4:c84afcfbac84 13 TimeZoneEntry* next;
hlipka 0:ab93db24fcc8 14 };
hlipka 0:ab93db24fcc8 15
hlipka 4:c84afcfbac84 16 TimeZoneEntry* Time::_timeZoneEntries=NULL;
hlipka 0:ab93db24fcc8 17
hlipka 5:fde01b92a384 18 bool TimeStamp::isSame(TimeStamp* ts) {
hlipka 0:ab93db24fcc8 19 if (ts->getYear()!=getYear())
hlipka 0:ab93db24fcc8 20 return false;
hlipka 0:ab93db24fcc8 21 if (ts->getMonth()!=getMonth())
hlipka 0:ab93db24fcc8 22 return false;
hlipka 0:ab93db24fcc8 23 if (ts->getDay()!=getDay())
hlipka 0:ab93db24fcc8 24 return false;
hlipka 0:ab93db24fcc8 25 if (ts->getHour()!=getHour())
hlipka 0:ab93db24fcc8 26 return false;
hlipka 0:ab93db24fcc8 27 if (ts->getSecond()!=getSecond())
hlipka 0:ab93db24fcc8 28 return false;
hlipka 0:ab93db24fcc8 29 return true;
hlipka 0:ab93db24fcc8 30 }
hlipka 5:fde01b92a384 31 bool TimeStamp::isBefore(TimeStamp* ts) {
hlipka 0:ab93db24fcc8 32 if (getYear()<ts->getYear())
hlipka 0:ab93db24fcc8 33 return true;
hlipka 0:ab93db24fcc8 34 if (getYear()>ts->getYear())
hlipka 0:ab93db24fcc8 35 return false;
hlipka 0:ab93db24fcc8 36
hlipka 0:ab93db24fcc8 37 if (getMonth()<ts->getMonth())
hlipka 0:ab93db24fcc8 38 return true;
hlipka 0:ab93db24fcc8 39 if (getMonth()>ts->getMonth())
hlipka 0:ab93db24fcc8 40 return false;
hlipka 0:ab93db24fcc8 41
hlipka 0:ab93db24fcc8 42 if (getDay()<ts->getDay())
hlipka 0:ab93db24fcc8 43 return true;
hlipka 0:ab93db24fcc8 44 if (getDay()>ts->getDay())
hlipka 0:ab93db24fcc8 45 return false;
hlipka 0:ab93db24fcc8 46
hlipka 0:ab93db24fcc8 47 if (getHour()<ts->getHour())
hlipka 0:ab93db24fcc8 48 return true;
hlipka 0:ab93db24fcc8 49 if (getHour()>ts->getHour())
hlipka 0:ab93db24fcc8 50 return false;
hlipka 0:ab93db24fcc8 51
hlipka 0:ab93db24fcc8 52 if (getSecond()<ts->getSecond())
hlipka 0:ab93db24fcc8 53 return true;
hlipka 5:fde01b92a384 54 return false;
hlipka 0:ab93db24fcc8 55 }
hlipka 5:fde01b92a384 56 bool TimeStamp::isAfter(TimeStamp* ts) {
hlipka 5:fde01b92a384 57 return ts->isBefore(this);
hlipka 0:ab93db24fcc8 58 }
hlipka 0:ab93db24fcc8 59
hlipka 0:ab93db24fcc8 60 Time::Time() {
hlipka 4:c84afcfbac84 61 // printf("init time\n");
hlipka 0:ab93db24fcc8 62 if (NULL==Time::_timeZoneEntries) {
hlipka 4:c84afcfbac84 63 // printf("reading time zones\n");
hlipka 0:ab93db24fcc8 64 readTimeZones();
hlipka 0:ab93db24fcc8 65 }
hlipka 0:ab93db24fcc8 66 }
hlipka 0:ab93db24fcc8 67
hlipka 0:ab93db24fcc8 68 void Time::readTimeZones() {
hlipka 0:ab93db24fcc8 69 time_t rawtime;
hlipka 0:ab93db24fcc8 70 time ( &rawtime );
hlipka 4:c84afcfbac84 71 TimeStamp *ts=new TimeStamp(rawtime);
hlipka 0:ab93db24fcc8 72
hlipka 4:c84afcfbac84 73 int currentYear=ts->getYear();
hlipka 4:c84afcfbac84 74 delete ts;
hlipka 0:ab93db24fcc8 75
hlipka 0:ab93db24fcc8 76 FILE *fp = fopen("/local/timezone.csv", "r");
hlipka 0:ab93db24fcc8 77
hlipka 0:ab93db24fcc8 78 if (fp==NULL) {
hlipka 0:ab93db24fcc8 79 printf("error while reading timezone file [timezone.csv]\n");
hlipka 0:ab93db24fcc8 80 return;
hlipka 0:ab93db24fcc8 81 }
hlipka 5:fde01b92a384 82
hlipka 4:c84afcfbac84 83 TimeZoneEntry *current=NULL;
hlipka 0:ab93db24fcc8 84
hlipka 0:ab93db24fcc8 85
hlipka 0:ab93db24fcc8 86 char tmp[128]; // enough for a single line
hlipka 0:ab93db24fcc8 87 while (fgets(tmp,sizeof(tmp),fp)!=0) {
hlipka 5:fde01b92a384 88 if (tmp[0]!='#') {
hlipka 5:fde01b92a384 89 int fyear, fmon, fday, fhour, fmin, fsec;
hlipka 5:fde01b92a384 90 int tyear, tmon, tday, thour, tmin, tsec;
hlipka 5:fde01b92a384 91 int offset;
hlipka 5:fde01b92a384 92 int r=sscanf(tmp,"%4d-%2d-%2dT%2d:%2d:%2dZ,%4d-%2d-%2dT%2d:%2d:%2dZ,%d",
hlipka 5:fde01b92a384 93 &fyear, &fmon, &fday, &fhour, &fmin, &fsec,
hlipka 5:fde01b92a384 94 &tyear, &tmon, &tday, &thour, &tmin, &tsec,
hlipka 5:fde01b92a384 95 &offset
hlipka 5:fde01b92a384 96 );
hlipka 5:fde01b92a384 97 if (13!=r)
hlipka 5:fde01b92a384 98 continue;
hlipka 5:fde01b92a384 99 // when we have no current time, so the year is 1970 and we read everything
hlipka 5:fde01b92a384 100 // otherwise skip everything more than 4 years in advance to save memory
hlipka 5:fde01b92a384 101 if (currentYear!=1970 && (tyear<currentYear || fyear>currentYear+4)) {
hlipka 5:fde01b92a384 102 continue;
hlipka 5:fde01b92a384 103 }
hlipka 5:fde01b92a384 104
hlipka 5:fde01b92a384 105 TimeStamp *from=new TimeStamp(fyear, fmon, fday, fhour, fmin, fsec,0);
hlipka 5:fde01b92a384 106 TimeStamp *to=new TimeStamp(tyear, tmon, tday, thour, tmin, tsec,0);
hlipka 5:fde01b92a384 107 TimeZoneEntry *tze=new TimeZoneEntry();
hlipka 5:fde01b92a384 108 tze->_from=from;
hlipka 5:fde01b92a384 109 tze->_to=to;
hlipka 5:fde01b92a384 110 tze->_offset=offset;
hlipka 5:fde01b92a384 111 tze->next=NULL;
hlipka 5:fde01b92a384 112
hlipka 5:fde01b92a384 113 if (NULL==current) {
hlipka 5:fde01b92a384 114 current=tze;
hlipka 5:fde01b92a384 115 _timeZoneEntries=tze;
hlipka 5:fde01b92a384 116 } else {
hlipka 5:fde01b92a384 117 current->next=tze;
hlipka 5:fde01b92a384 118 current=tze;
hlipka 5:fde01b92a384 119 }
hlipka 4:c84afcfbac84 120 }
hlipka 0:ab93db24fcc8 121 }
hlipka 5:fde01b92a384 122 // printf("closing time zone file\n");
hlipka 0:ab93db24fcc8 123 fclose(fp);
hlipka 0:ab93db24fcc8 124 }
hlipka 0:ab93db24fcc8 125
hlipka 0:ab93db24fcc8 126 Time::~Time() {
hlipka 0:ab93db24fcc8 127 }
hlipka 0:ab93db24fcc8 128
hlipka 5:fde01b92a384 129 int Time::getTimeOffset(TimeStamp* ts) {
hlipka 5:fde01b92a384 130 TimeZoneEntry *current=_timeZoneEntries;
hlipka 5:fde01b92a384 131
hlipka 5:fde01b92a384 132 while (current!=NULL) {
hlipka 5:fde01b92a384 133 if (current->_from->isBefore(ts) && current->_to->isAfter(ts)) {
hlipka 5:fde01b92a384 134 return current->_offset;
hlipka 5:fde01b92a384 135 }
hlipka 5:fde01b92a384 136 current=current->next;
hlipka 5:fde01b92a384 137 }
hlipka 5:fde01b92a384 138 return 0;
hlipka 5:fde01b92a384 139 }
hlipka 5:fde01b92a384 140
hlipka 0:ab93db24fcc8 141 TimeStamp* Time::getTime() {
hlipka 0:ab93db24fcc8 142 time_t rawtime;
hlipka 0:ab93db24fcc8 143 time ( &rawtime );
hlipka 0:ab93db24fcc8 144 TimeStamp *ts=new TimeStamp(rawtime);
hlipka 5:fde01b92a384 145
hlipka 5:fde01b92a384 146 rawtime+=getTimeOffset(ts);
hlipka 5:fde01b92a384 147 ts->updateTime(rawtime);
hlipka 5:fde01b92a384 148
hlipka 0:ab93db24fcc8 149 return ts;
hlipka 0:ab93db24fcc8 150 }