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@7:0c7207d674d3, 2011-02-18 (annotated)
- Committer:
- hlipka
- Date:
- Fri Feb 18 13:15:35 2011 +0000
- Revision:
- 7:0c7207d674d3
- Parent:
- 5:fde01b92a384
added license
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hlipka | 7:0c7207d674d3 | 1 | /* |
hlipka | 7:0c7207d674d3 | 2 | * TimeZone library |
hlipka | 7:0c7207d674d3 | 3 | * Copyright (c) 2010 Hendrik Lipka |
hlipka | 7:0c7207d674d3 | 4 | * |
hlipka | 7:0c7207d674d3 | 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
hlipka | 7:0c7207d674d3 | 6 | * of this software and associated documentation files (the "Software"), to deal |
hlipka | 7:0c7207d674d3 | 7 | * in the Software without restriction, including without limitation the rights |
hlipka | 7:0c7207d674d3 | 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
hlipka | 7:0c7207d674d3 | 9 | * copies of the Software, and to permit persons to whom the Software is |
hlipka | 7:0c7207d674d3 | 10 | * furnished to do so, subject to the following conditions: |
hlipka | 7:0c7207d674d3 | 11 | * |
hlipka | 7:0c7207d674d3 | 12 | * The above copyright notice and this permission notice shall be included in |
hlipka | 7:0c7207d674d3 | 13 | * all copies or substantial portions of the Software. |
hlipka | 7:0c7207d674d3 | 14 | * |
hlipka | 7:0c7207d674d3 | 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
hlipka | 7:0c7207d674d3 | 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
hlipka | 7:0c7207d674d3 | 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
hlipka | 7:0c7207d674d3 | 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
hlipka | 7:0c7207d674d3 | 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
hlipka | 7:0c7207d674d3 | 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
hlipka | 7:0c7207d674d3 | 21 | * THE SOFTWARE. |
hlipka | 7:0c7207d674d3 | 22 | */ |
hlipka | 7:0c7207d674d3 | 23 | |
hlipka | 0:ab93db24fcc8 | 24 | #include "Time.h" |
hlipka | 0:ab93db24fcc8 | 25 | |
hlipka | 0:ab93db24fcc8 | 26 | #include "stdio.h" |
hlipka | 0:ab93db24fcc8 | 27 | #include "time.h" |
hlipka | 0:ab93db24fcc8 | 28 | |
hlipka | 0:ab93db24fcc8 | 29 | using namespace std; |
hlipka | 0:ab93db24fcc8 | 30 | |
hlipka | 0:ab93db24fcc8 | 31 | class TimeZoneEntry { |
hlipka | 5:fde01b92a384 | 32 | public: |
hlipka | 0:ab93db24fcc8 | 33 | TimeStamp *_from; |
hlipka | 0:ab93db24fcc8 | 34 | TimeStamp *_to; |
hlipka | 0:ab93db24fcc8 | 35 | int _offset; |
hlipka | 4:c84afcfbac84 | 36 | TimeZoneEntry* next; |
hlipka | 0:ab93db24fcc8 | 37 | }; |
hlipka | 0:ab93db24fcc8 | 38 | |
hlipka | 4:c84afcfbac84 | 39 | TimeZoneEntry* Time::_timeZoneEntries=NULL; |
hlipka | 0:ab93db24fcc8 | 40 | |
hlipka | 5:fde01b92a384 | 41 | bool TimeStamp::isSame(TimeStamp* ts) { |
hlipka | 0:ab93db24fcc8 | 42 | if (ts->getYear()!=getYear()) |
hlipka | 0:ab93db24fcc8 | 43 | return false; |
hlipka | 0:ab93db24fcc8 | 44 | if (ts->getMonth()!=getMonth()) |
hlipka | 0:ab93db24fcc8 | 45 | return false; |
hlipka | 0:ab93db24fcc8 | 46 | if (ts->getDay()!=getDay()) |
hlipka | 0:ab93db24fcc8 | 47 | return false; |
hlipka | 0:ab93db24fcc8 | 48 | if (ts->getHour()!=getHour()) |
hlipka | 0:ab93db24fcc8 | 49 | return false; |
hlipka | 0:ab93db24fcc8 | 50 | if (ts->getSecond()!=getSecond()) |
hlipka | 0:ab93db24fcc8 | 51 | return false; |
hlipka | 0:ab93db24fcc8 | 52 | return true; |
hlipka | 0:ab93db24fcc8 | 53 | } |
hlipka | 5:fde01b92a384 | 54 | bool TimeStamp::isBefore(TimeStamp* ts) { |
hlipka | 0:ab93db24fcc8 | 55 | if (getYear()<ts->getYear()) |
hlipka | 0:ab93db24fcc8 | 56 | return true; |
hlipka | 0:ab93db24fcc8 | 57 | if (getYear()>ts->getYear()) |
hlipka | 0:ab93db24fcc8 | 58 | return false; |
hlipka | 0:ab93db24fcc8 | 59 | |
hlipka | 0:ab93db24fcc8 | 60 | if (getMonth()<ts->getMonth()) |
hlipka | 0:ab93db24fcc8 | 61 | return true; |
hlipka | 0:ab93db24fcc8 | 62 | if (getMonth()>ts->getMonth()) |
hlipka | 0:ab93db24fcc8 | 63 | return false; |
hlipka | 0:ab93db24fcc8 | 64 | |
hlipka | 0:ab93db24fcc8 | 65 | if (getDay()<ts->getDay()) |
hlipka | 0:ab93db24fcc8 | 66 | return true; |
hlipka | 0:ab93db24fcc8 | 67 | if (getDay()>ts->getDay()) |
hlipka | 0:ab93db24fcc8 | 68 | return false; |
hlipka | 0:ab93db24fcc8 | 69 | |
hlipka | 0:ab93db24fcc8 | 70 | if (getHour()<ts->getHour()) |
hlipka | 0:ab93db24fcc8 | 71 | return true; |
hlipka | 0:ab93db24fcc8 | 72 | if (getHour()>ts->getHour()) |
hlipka | 0:ab93db24fcc8 | 73 | return false; |
hlipka | 0:ab93db24fcc8 | 74 | |
hlipka | 0:ab93db24fcc8 | 75 | if (getSecond()<ts->getSecond()) |
hlipka | 0:ab93db24fcc8 | 76 | return true; |
hlipka | 5:fde01b92a384 | 77 | return false; |
hlipka | 0:ab93db24fcc8 | 78 | } |
hlipka | 5:fde01b92a384 | 79 | bool TimeStamp::isAfter(TimeStamp* ts) { |
hlipka | 5:fde01b92a384 | 80 | return ts->isBefore(this); |
hlipka | 0:ab93db24fcc8 | 81 | } |
hlipka | 0:ab93db24fcc8 | 82 | |
hlipka | 0:ab93db24fcc8 | 83 | Time::Time() { |
hlipka | 4:c84afcfbac84 | 84 | // printf("init time\n"); |
hlipka | 0:ab93db24fcc8 | 85 | if (NULL==Time::_timeZoneEntries) { |
hlipka | 4:c84afcfbac84 | 86 | // printf("reading time zones\n"); |
hlipka | 0:ab93db24fcc8 | 87 | readTimeZones(); |
hlipka | 0:ab93db24fcc8 | 88 | } |
hlipka | 0:ab93db24fcc8 | 89 | } |
hlipka | 0:ab93db24fcc8 | 90 | |
hlipka | 0:ab93db24fcc8 | 91 | void Time::readTimeZones() { |
hlipka | 0:ab93db24fcc8 | 92 | time_t rawtime; |
hlipka | 0:ab93db24fcc8 | 93 | time ( &rawtime ); |
hlipka | 4:c84afcfbac84 | 94 | TimeStamp *ts=new TimeStamp(rawtime); |
hlipka | 0:ab93db24fcc8 | 95 | |
hlipka | 4:c84afcfbac84 | 96 | int currentYear=ts->getYear(); |
hlipka | 4:c84afcfbac84 | 97 | delete ts; |
hlipka | 0:ab93db24fcc8 | 98 | |
hlipka | 0:ab93db24fcc8 | 99 | FILE *fp = fopen("/local/timezone.csv", "r"); |
hlipka | 0:ab93db24fcc8 | 100 | |
hlipka | 0:ab93db24fcc8 | 101 | if (fp==NULL) { |
hlipka | 0:ab93db24fcc8 | 102 | printf("error while reading timezone file [timezone.csv]\n"); |
hlipka | 0:ab93db24fcc8 | 103 | return; |
hlipka | 0:ab93db24fcc8 | 104 | } |
hlipka | 5:fde01b92a384 | 105 | |
hlipka | 4:c84afcfbac84 | 106 | TimeZoneEntry *current=NULL; |
hlipka | 0:ab93db24fcc8 | 107 | |
hlipka | 0:ab93db24fcc8 | 108 | |
hlipka | 0:ab93db24fcc8 | 109 | char tmp[128]; // enough for a single line |
hlipka | 0:ab93db24fcc8 | 110 | while (fgets(tmp,sizeof(tmp),fp)!=0) { |
hlipka | 5:fde01b92a384 | 111 | if (tmp[0]!='#') { |
hlipka | 5:fde01b92a384 | 112 | int fyear, fmon, fday, fhour, fmin, fsec; |
hlipka | 5:fde01b92a384 | 113 | int tyear, tmon, tday, thour, tmin, tsec; |
hlipka | 5:fde01b92a384 | 114 | int offset; |
hlipka | 5:fde01b92a384 | 115 | int r=sscanf(tmp,"%4d-%2d-%2dT%2d:%2d:%2dZ,%4d-%2d-%2dT%2d:%2d:%2dZ,%d", |
hlipka | 5:fde01b92a384 | 116 | &fyear, &fmon, &fday, &fhour, &fmin, &fsec, |
hlipka | 5:fde01b92a384 | 117 | &tyear, &tmon, &tday, &thour, &tmin, &tsec, |
hlipka | 5:fde01b92a384 | 118 | &offset |
hlipka | 5:fde01b92a384 | 119 | ); |
hlipka | 5:fde01b92a384 | 120 | if (13!=r) |
hlipka | 5:fde01b92a384 | 121 | continue; |
hlipka | 5:fde01b92a384 | 122 | // when we have no current time, so the year is 1970 and we read everything |
hlipka | 5:fde01b92a384 | 123 | // otherwise skip everything more than 4 years in advance to save memory |
hlipka | 5:fde01b92a384 | 124 | if (currentYear!=1970 && (tyear<currentYear || fyear>currentYear+4)) { |
hlipka | 5:fde01b92a384 | 125 | continue; |
hlipka | 5:fde01b92a384 | 126 | } |
hlipka | 5:fde01b92a384 | 127 | |
hlipka | 5:fde01b92a384 | 128 | TimeStamp *from=new TimeStamp(fyear, fmon, fday, fhour, fmin, fsec,0); |
hlipka | 5:fde01b92a384 | 129 | TimeStamp *to=new TimeStamp(tyear, tmon, tday, thour, tmin, tsec,0); |
hlipka | 5:fde01b92a384 | 130 | TimeZoneEntry *tze=new TimeZoneEntry(); |
hlipka | 5:fde01b92a384 | 131 | tze->_from=from; |
hlipka | 5:fde01b92a384 | 132 | tze->_to=to; |
hlipka | 5:fde01b92a384 | 133 | tze->_offset=offset; |
hlipka | 5:fde01b92a384 | 134 | tze->next=NULL; |
hlipka | 5:fde01b92a384 | 135 | |
hlipka | 5:fde01b92a384 | 136 | if (NULL==current) { |
hlipka | 5:fde01b92a384 | 137 | current=tze; |
hlipka | 5:fde01b92a384 | 138 | _timeZoneEntries=tze; |
hlipka | 5:fde01b92a384 | 139 | } else { |
hlipka | 5:fde01b92a384 | 140 | current->next=tze; |
hlipka | 5:fde01b92a384 | 141 | current=tze; |
hlipka | 5:fde01b92a384 | 142 | } |
hlipka | 4:c84afcfbac84 | 143 | } |
hlipka | 0:ab93db24fcc8 | 144 | } |
hlipka | 5:fde01b92a384 | 145 | // printf("closing time zone file\n"); |
hlipka | 0:ab93db24fcc8 | 146 | fclose(fp); |
hlipka | 0:ab93db24fcc8 | 147 | } |
hlipka | 0:ab93db24fcc8 | 148 | |
hlipka | 0:ab93db24fcc8 | 149 | Time::~Time() { |
hlipka | 0:ab93db24fcc8 | 150 | } |
hlipka | 0:ab93db24fcc8 | 151 | |
hlipka | 5:fde01b92a384 | 152 | int Time::getTimeOffset(TimeStamp* ts) { |
hlipka | 5:fde01b92a384 | 153 | TimeZoneEntry *current=_timeZoneEntries; |
hlipka | 5:fde01b92a384 | 154 | |
hlipka | 5:fde01b92a384 | 155 | while (current!=NULL) { |
hlipka | 5:fde01b92a384 | 156 | if (current->_from->isBefore(ts) && current->_to->isAfter(ts)) { |
hlipka | 5:fde01b92a384 | 157 | return current->_offset; |
hlipka | 5:fde01b92a384 | 158 | } |
hlipka | 5:fde01b92a384 | 159 | current=current->next; |
hlipka | 5:fde01b92a384 | 160 | } |
hlipka | 5:fde01b92a384 | 161 | return 0; |
hlipka | 5:fde01b92a384 | 162 | } |
hlipka | 5:fde01b92a384 | 163 | |
hlipka | 0:ab93db24fcc8 | 164 | TimeStamp* Time::getTime() { |
hlipka | 0:ab93db24fcc8 | 165 | time_t rawtime; |
hlipka | 0:ab93db24fcc8 | 166 | time ( &rawtime ); |
hlipka | 0:ab93db24fcc8 | 167 | TimeStamp *ts=new TimeStamp(rawtime); |
hlipka | 5:fde01b92a384 | 168 | |
hlipka | 5:fde01b92a384 | 169 | rawtime+=getTimeOffset(ts); |
hlipka | 5:fde01b92a384 | 170 | ts->updateTime(rawtime); |
hlipka | 5:fde01b92a384 | 171 | |
hlipka | 0:ab93db24fcc8 | 172 | return ts; |
hlipka | 0:ab93db24fcc8 | 173 | } |