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
- Committer:
- hlipka
- Date:
- 2011-02-18
- Revision:
- 7:0c7207d674d3
- Parent:
- 5:fde01b92a384
File content as of revision 7:0c7207d674d3:
/* * TimeZone library * Copyright (c) 2010 Hendrik Lipka * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "Time.h" #include "stdio.h" #include "time.h" using namespace std; class TimeZoneEntry { public: TimeStamp *_from; TimeStamp *_to; int _offset; TimeZoneEntry* next; }; TimeZoneEntry* Time::_timeZoneEntries=NULL; bool TimeStamp::isSame(TimeStamp* ts) { if (ts->getYear()!=getYear()) return false; if (ts->getMonth()!=getMonth()) return false; if (ts->getDay()!=getDay()) return false; if (ts->getHour()!=getHour()) return false; if (ts->getSecond()!=getSecond()) return false; return true; } bool TimeStamp::isBefore(TimeStamp* ts) { if (getYear()<ts->getYear()) return true; if (getYear()>ts->getYear()) return false; if (getMonth()<ts->getMonth()) return true; if (getMonth()>ts->getMonth()) return false; if (getDay()<ts->getDay()) return true; if (getDay()>ts->getDay()) return false; if (getHour()<ts->getHour()) return true; if (getHour()>ts->getHour()) return false; if (getSecond()<ts->getSecond()) return true; return false; } bool TimeStamp::isAfter(TimeStamp* ts) { return ts->isBefore(this); } Time::Time() { // printf("init time\n"); if (NULL==Time::_timeZoneEntries) { // printf("reading time zones\n"); readTimeZones(); } } void Time::readTimeZones() { time_t rawtime; time ( &rawtime ); TimeStamp *ts=new TimeStamp(rawtime); int currentYear=ts->getYear(); delete ts; FILE *fp = fopen("/local/timezone.csv", "r"); if (fp==NULL) { 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) { 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"); 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); rawtime+=getTimeOffset(ts); ts->updateTime(rawtime); return ts; }