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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Time.cpp Source File

Time.cpp

00001 /*
00002 * TimeZone library
00003 * Copyright (c) 2010 Hendrik Lipka
00004 * 
00005 * Permission is hereby granted, free of charge, to any person obtaining a copy
00006 * of this software and associated documentation files (the "Software"), to deal
00007 * in the Software without restriction, including without limitation the rights
00008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 * copies of the Software, and to permit persons to whom the Software is
00010 * furnished to do so, subject to the following conditions:
00011 * 
00012 * The above copyright notice and this permission notice shall be included in
00013 * all copies or substantial portions of the Software.
00014 * 
00015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 * THE SOFTWARE.
00022 */
00023 
00024 #include "Time.h"
00025 
00026 #include "stdio.h"
00027 #include "time.h"
00028 
00029 using namespace std;
00030 
00031 class TimeZoneEntry {
00032 public:
00033     TimeStamp *_from;
00034     TimeStamp *_to;
00035     int _offset;
00036     TimeZoneEntry* next;
00037 };
00038 
00039 TimeZoneEntry* Time::_timeZoneEntries=NULL;
00040 
00041 bool TimeStamp::isSame (TimeStamp* ts) {
00042     if (ts->getYear ()!=getYear())
00043         return false;
00044     if (ts->getMonth ()!=getMonth())
00045         return false;
00046     if (ts->getDay ()!=getDay())
00047         return false;
00048     if (ts->getHour ()!=getHour())
00049         return false;
00050     if (ts->getSecond ()!=getSecond())
00051         return false;
00052     return true;
00053 }
00054 bool TimeStamp::isBefore (TimeStamp* ts) {
00055     if (getYear()<ts->getYear ())
00056         return true;
00057     if (getYear()>ts->getYear ())
00058         return false;
00059 
00060     if (getMonth()<ts->getMonth ())
00061         return true;
00062     if (getMonth()>ts->getMonth ())
00063         return false;
00064 
00065     if (getDay()<ts->getDay ())
00066         return true;
00067     if (getDay()>ts->getDay ())
00068         return false;
00069 
00070     if (getHour()<ts->getHour ())
00071         return true;
00072     if (getHour()>ts->getHour ())
00073         return false;
00074 
00075     if (getSecond()<ts->getSecond ())
00076         return true;
00077     return false;
00078 }
00079 bool TimeStamp::isAfter (TimeStamp* ts) {
00080     return ts->isBefore (this);
00081 }
00082 
00083 Time::Time() {
00084 //    printf("init time\n");
00085     if (NULL==Time::_timeZoneEntries) {
00086 //        printf("reading time zones\n");
00087         readTimeZones();
00088     }
00089 }
00090 
00091 void Time::readTimeZones() {
00092     time_t rawtime;
00093     time ( &rawtime );
00094     TimeStamp *ts=new TimeStamp(rawtime);
00095 
00096     int currentYear=ts->getYear ();
00097     delete ts;
00098 
00099     FILE *fp = fopen("/local/timezone.csv", "r");
00100 
00101     if (fp==NULL) {
00102         printf("error while reading timezone file [timezone.csv]\n");
00103         return;
00104     }
00105 
00106     TimeZoneEntry *current=NULL;
00107 
00108 
00109     char tmp[128]; // enough for a single line
00110     while (fgets(tmp,sizeof(tmp),fp)!=0) {
00111         if (tmp[0]!='#') {
00112             int fyear, fmon, fday, fhour, fmin, fsec;
00113             int tyear, tmon, tday, thour, tmin, tsec;
00114             int offset;
00115             int r=sscanf(tmp,"%4d-%2d-%2dT%2d:%2d:%2dZ,%4d-%2d-%2dT%2d:%2d:%2dZ,%d",
00116                          &fyear, &fmon, &fday, &fhour, &fmin, &fsec,
00117                          &tyear, &tmon, &tday, &thour, &tmin, &tsec,
00118                          &offset
00119                         );
00120             if (13!=r)
00121                 continue;
00122             // when we have no current time, so the year is 1970 and we read everything
00123             // otherwise skip everything more than 4 years in advance to save memory
00124             if (currentYear!=1970 && (tyear<currentYear || fyear>currentYear+4)) {
00125                 continue;
00126             }
00127 
00128             TimeStamp *from=new TimeStamp(fyear, fmon, fday, fhour, fmin, fsec,0);
00129             TimeStamp *to=new TimeStamp(tyear, tmon, tday, thour, tmin, tsec,0);
00130             TimeZoneEntry *tze=new TimeZoneEntry();
00131             tze->_from=from;
00132             tze->_to=to;
00133             tze->_offset=offset;
00134             tze->next=NULL;
00135 
00136             if (NULL==current) {
00137                 current=tze;
00138                 _timeZoneEntries=tze;
00139             } else {
00140                 current->next=tze;
00141                 current=tze;
00142             }
00143         }
00144     }
00145 //    printf("closing time zone file\n");
00146     fclose(fp);
00147 }
00148 
00149 Time::~Time() {
00150 }
00151 
00152 int Time::getTimeOffset(TimeStamp* ts) {
00153     TimeZoneEntry *current=_timeZoneEntries;
00154 
00155     while (current!=NULL) {
00156         if (current->_from->isBefore(ts) && current->_to->isAfter(ts)) {
00157             return current->_offset;
00158         }
00159         current=current->next;
00160     }
00161     return 0;
00162 }
00163 
00164 TimeStamp* Time::getTime() {
00165     time_t rawtime;
00166     time ( &rawtime );
00167     TimeStamp *ts=new TimeStamp(rawtime);
00168 
00169     rawtime+=getTimeOffset(ts);
00170     ts->updateTime(rawtime);
00171 
00172     return ts;
00173 }