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
Time.cpp@3:2ad51ec5ef6e, 2011-01-04 (annotated)
- Committer:
- hlipka
- Date:
- Tue Jan 04 23:19:50 2011 +0000
- Revision:
- 3:2ad51ec5ef6e
- Parent:
- 0:ab93db24fcc8
- Child:
- 4:c84afcfbac84
fixed reading of time zone entries (was missing the beginning of the year), months are starting with 1 now, updated documentation
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:ab93db24fcc8 | 9 | public: |
hlipka | 0:ab93db24fcc8 | 10 | TimeStamp *_from; |
hlipka | 0:ab93db24fcc8 | 11 | TimeStamp *_to; |
hlipka | 0:ab93db24fcc8 | 12 | int _offset; |
hlipka | 0:ab93db24fcc8 | 13 | }; |
hlipka | 0:ab93db24fcc8 | 14 | |
hlipka | 0:ab93db24fcc8 | 15 | list<TimeZoneEntry*> *Time::_timeZoneEntries=NULL; |
hlipka | 0:ab93db24fcc8 | 16 | |
hlipka | 0:ab93db24fcc8 | 17 | bool TimeStamp::isSame(TimeStamp* ts) |
hlipka | 0:ab93db24fcc8 | 18 | { |
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 | 0:ab93db24fcc8 | 31 | bool TimeStamp::isBefore(TimeStamp* ts) |
hlipka | 0:ab93db24fcc8 | 32 | { |
hlipka | 0:ab93db24fcc8 | 33 | if (getYear()<ts->getYear()) |
hlipka | 0:ab93db24fcc8 | 34 | return true; |
hlipka | 0:ab93db24fcc8 | 35 | if (getYear()>ts->getYear()) |
hlipka | 0:ab93db24fcc8 | 36 | return false; |
hlipka | 0:ab93db24fcc8 | 37 | |
hlipka | 0:ab93db24fcc8 | 38 | if (getMonth()<ts->getMonth()) |
hlipka | 0:ab93db24fcc8 | 39 | return true; |
hlipka | 0:ab93db24fcc8 | 40 | if (getMonth()>ts->getMonth()) |
hlipka | 0:ab93db24fcc8 | 41 | return false; |
hlipka | 0:ab93db24fcc8 | 42 | |
hlipka | 0:ab93db24fcc8 | 43 | if (getDay()<ts->getDay()) |
hlipka | 0:ab93db24fcc8 | 44 | return true; |
hlipka | 0:ab93db24fcc8 | 45 | if (getDay()>ts->getDay()) |
hlipka | 0:ab93db24fcc8 | 46 | return false; |
hlipka | 0:ab93db24fcc8 | 47 | |
hlipka | 0:ab93db24fcc8 | 48 | if (getHour()<ts->getHour()) |
hlipka | 0:ab93db24fcc8 | 49 | return true; |
hlipka | 0:ab93db24fcc8 | 50 | if (getHour()>ts->getHour()) |
hlipka | 0:ab93db24fcc8 | 51 | return false; |
hlipka | 0:ab93db24fcc8 | 52 | |
hlipka | 0:ab93db24fcc8 | 53 | if (getSecond()<ts->getSecond()) |
hlipka | 0:ab93db24fcc8 | 54 | return true; |
hlipka | 0:ab93db24fcc8 | 55 | return false; |
hlipka | 0:ab93db24fcc8 | 56 | } |
hlipka | 0:ab93db24fcc8 | 57 | bool TimeStamp::isAfter(TimeStamp* ts) |
hlipka | 0:ab93db24fcc8 | 58 | { |
hlipka | 0:ab93db24fcc8 | 59 | return ts->isBefore(this); |
hlipka | 0:ab93db24fcc8 | 60 | } |
hlipka | 0:ab93db24fcc8 | 61 | |
hlipka | 0:ab93db24fcc8 | 62 | Time::Time() { |
hlipka | 0:ab93db24fcc8 | 63 | if (NULL==Time::_timeZoneEntries) { |
hlipka | 0:ab93db24fcc8 | 64 | _timeZoneEntries=new list<TimeZoneEntry*>(); |
hlipka | 0:ab93db24fcc8 | 65 | readTimeZones(); |
hlipka | 0:ab93db24fcc8 | 66 | } |
hlipka | 0:ab93db24fcc8 | 67 | } |
hlipka | 0:ab93db24fcc8 | 68 | |
hlipka | 0:ab93db24fcc8 | 69 | void Time::readTimeZones() { |
hlipka | 0:ab93db24fcc8 | 70 | time_t rawtime; |
hlipka | 0:ab93db24fcc8 | 71 | time ( &rawtime ); |
hlipka | 0:ab93db24fcc8 | 72 | TimeStamp ts(rawtime); |
hlipka | 0:ab93db24fcc8 | 73 | |
hlipka | 0:ab93db24fcc8 | 74 | int currentYear=ts.getYear(); |
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 | 0:ab93db24fcc8 | 82 | |
hlipka | 0:ab93db24fcc8 | 83 | |
hlipka | 0:ab93db24fcc8 | 84 | char tmp[128]; // enough for a single line |
hlipka | 0:ab93db24fcc8 | 85 | while (fgets(tmp,sizeof(tmp),fp)!=0) { |
hlipka | 0:ab93db24fcc8 | 86 | int fyear, fmon, fday, fhour, fmin, fsec; |
hlipka | 0:ab93db24fcc8 | 87 | int tyear, tmon, tday, thour, tmin, tsec; |
hlipka | 0:ab93db24fcc8 | 88 | int offset; |
hlipka | 0:ab93db24fcc8 | 89 | int r=sscanf(tmp,"%4d-%2d-%2dT%2d:%2d:%2dZ,%4d-%2d-%2dT%2d:%2d:%2dZ,%d", |
hlipka | 0:ab93db24fcc8 | 90 | &fyear, &fmon, &fday, &fhour, &fmin, &fsec, |
hlipka | 0:ab93db24fcc8 | 91 | &tyear, &tmon, &tday, &thour, &tmin, &tsec, |
hlipka | 0:ab93db24fcc8 | 92 | &offset |
hlipka | 0:ab93db24fcc8 | 93 | ); |
hlipka | 0:ab93db24fcc8 | 94 | if (13!=r) |
hlipka | 0:ab93db24fcc8 | 95 | continue; |
hlipka | 3:2ad51ec5ef6e | 96 | if (tyear<currentYear || fyear>currentYear+4) |
hlipka | 0:ab93db24fcc8 | 97 | continue; |
hlipka | 0:ab93db24fcc8 | 98 | |
hlipka | 0:ab93db24fcc8 | 99 | TimeStamp *from=new TimeStamp(fyear, fmon, fday, fhour, fmin, fsec); |
hlipka | 0:ab93db24fcc8 | 100 | TimeStamp *to=new TimeStamp(tyear, tmon, tday, thour, tmin, tsec); |
hlipka | 0:ab93db24fcc8 | 101 | TimeZoneEntry *tze=new TimeZoneEntry(); |
hlipka | 0:ab93db24fcc8 | 102 | tze->_from=from; |
hlipka | 0:ab93db24fcc8 | 103 | tze->_to=to; |
hlipka | 0:ab93db24fcc8 | 104 | tze->_offset=offset; |
hlipka | 0:ab93db24fcc8 | 105 | _timeZoneEntries->push_back(tze); |
hlipka | 0:ab93db24fcc8 | 106 | } |
hlipka | 0:ab93db24fcc8 | 107 | |
hlipka | 0:ab93db24fcc8 | 108 | fclose(fp); |
hlipka | 0:ab93db24fcc8 | 109 | } |
hlipka | 0:ab93db24fcc8 | 110 | |
hlipka | 0:ab93db24fcc8 | 111 | Time::~Time() { |
hlipka | 0:ab93db24fcc8 | 112 | } |
hlipka | 0:ab93db24fcc8 | 113 | |
hlipka | 0:ab93db24fcc8 | 114 | TimeStamp* Time::getTime() { |
hlipka | 0:ab93db24fcc8 | 115 | time_t rawtime; |
hlipka | 0:ab93db24fcc8 | 116 | time ( &rawtime ); |
hlipka | 0:ab93db24fcc8 | 117 | TimeStamp *ts=new TimeStamp(rawtime); |
hlipka | 3:2ad51ec5ef6e | 118 | |
hlipka | 0:ab93db24fcc8 | 119 | for (list<TimeZoneEntry*>::iterator it = _timeZoneEntries->begin(); it != _timeZoneEntries->end(); it++) { |
hlipka | 0:ab93db24fcc8 | 120 | TimeZoneEntry* tze=*it; |
hlipka | 0:ab93db24fcc8 | 121 | if (tze->_from->isBefore(ts) && tze->_to->isAfter(ts)) |
hlipka | 0:ab93db24fcc8 | 122 | { |
hlipka | 0:ab93db24fcc8 | 123 | rawtime+=tze->_offset; |
hlipka | 0:ab93db24fcc8 | 124 | ts->updateTime(rawtime); |
hlipka | 3:2ad51ec5ef6e | 125 | break; |
hlipka | 0:ab93db24fcc8 | 126 | } |
hlipka | 0:ab93db24fcc8 | 127 | } |
hlipka | 0:ab93db24fcc8 | 128 | |
hlipka | 0:ab93db24fcc8 | 129 | return ts; |
hlipka | 0:ab93db24fcc8 | 130 | } |