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:
Fri Feb 18 13:15:35 2011 +0000
Revision:
7:0c7207d674d3
Parent:
5:fde01b92a384
added license

Who changed what in which revision?

UserRevisionLine numberNew 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 }