Reputation: 493
I need to convert some string times in the format "2011061411322100" into GMT - my first attempt is below. However, the problem is that the times are coming from another PC and is a historical time. So I am not getting the times in real time so I cannot simply get the GMT from the local time on the box that my code is running.
The problem is that if my code is running during a time change, the time change will have occurred on my box but not on the remote box where I am getting the times. I can however, query the box to get the current time at any time.
So, to give more detail:
If a time change (daylight savings) occurs between 1. and 2. I am screwed. My GMT conversion will break. I guess after 2) I need to get the current Remote Box time and see if there is a difference of >58 mins and then apply that to the conversion. But I cannot figure out a reliable method of doing this.
string GMTConverter::strToGMT(const string& timeToConvert)
{
// Set time zone from TZ environment variable.
_tzset();
struct tm tmTime;
//2011 06 14 11 32 21 00
// (strToInt is just a wrapper for atoi)
int year = strToint(timeToConvert.substr(0, 4) );
int month = strToint(timeToConvert.substr(4, 2) );
int day = strToint(timeToConvert.substr(6, 2) );
int hour = strToint(timeToConvert.substr(8, 2) );
int min = strToint(timeToConvert.substr(10, 2) );
int sec = strToint(timeToConvert.substr(12, 2) );
cout<<"Time after parsing: "<<year<<"/"<<month<<"/"<<day<<" "<<hour<<":"<<min<<":"<<sec<<endl;
// add to tm struct and return
tmTime.tm_hour = hour;
tmTime.tm_min = min;
tmTime.tm_sec = sec;
tmTime.tm_mday = day;
tmTime.tm_mon = (month-1);
tmTime.tm_year = (year - 1900);
cout <<"Time in TM: "<<tmTime.tm_year<<"/"<<tmTime.tm_mon<<"/"<<tmTime.tm_mday<<" "<<tmTime.tm_hour<<":"<<tmTime.tm_min<<":"<<tmTime.tm_sec<<endl;
char currDateTime[64];
// For logging
strftime(currDateTime, 63, "%c", &tmTime);
cout <<"Actual time:"<<currDateTime<<endl;
time_t remotePCTime = mktime( &tmTime );
struct tm *gmt = gmtime( &remotePCTime );
cout << "gmt = " << asctime( gmt ) << endl;
char datebuf_2[12];
char timebuf_2[13];
strftime( datebuf_2, 13, "%Y-%m-%d\0", gmt );
strftime( timebuf_2, 13, "%H:%M:%S\0", gmt );
return string(datebuf_2) + "T" + string(timebuf_2) + "." + string("000");
}
Upvotes: 2
Views: 793
Reputation: 8720
Get the local time in UTC at the start and end of the remote job. Get the remote job time and covert to UTC at the start and end of the job. Convert the collection "historic" times to GMT/UTC as stated in your original post. Keep this data together in a struct or class and give additional start end times a clear name like LocalDLSValidation etc We must now checkfor following scenarios:
1. Start and end time delta between Local and Remote is within allowed threshold(50mins?)
This the gold case. No modification is required to our collection of historical times
2. Local start/end time and remote time delta is outside threshold.
This is the second simplest case. It means that we can + or - hour to our entire collection of times.
3.Local start time and remote time delta is within threshold. But end is outside.
This is our worst case scenario as it means change has occurred in the middle of our job. If the job lasts less than hour then it will be easy to see which times in our collection need to be + or - one hour.
If it is greater than 1 hour....mmmmm. This is where we run into problems.
4. Start time between local and remote is different but end time is different
According to use case in OP this should not occur.
Upvotes: 1
Reputation: 46
The obvious reliable solution would be to use UTC (which has no daylight savings) for the time stamp you're sending over. Using any time system that has inherent ambiguity (there is one hour of overlap each year where you can get the same time stamps on a different time) will make it impossible to have a fool-proof method, since information is lost.
If you have no control over the time format that the remote machine is sending, you can only try to extrapolate from the information that you do have, for instance, if the end time is lower than the start time, add one hour. This again introduces ambiguity if the job took longer than one hour, but at least time won't move backwards.
Upvotes: 2
Reputation: 3087
Time change appears twice a year - why should you bother? Anyway, can't you change the time format to include the time change event? Or check if job is done during time change by comparing to some fixed time and date at which time change appears?
Upvotes: 1