Преобразовать историческое время в GMT - PullRequest
2 голосов
/ 27 июня 2011

Мне нужно преобразовать несколько строк в формате «2011061411322100» в GMT - моя первая попытка приведена ниже. Однако проблема в том, что времена идут с другого компьютера и это историческое время. Поэтому я не получаю время в режиме реального времени, поэтому я не могу просто получить GMT по местному времени на коробке, в которой работает мой код.

Проблема в том, что если мой код работает во время изменения времени, изменение времени произойдет на моем ящике, а не на удаленном ящике, где я получаю время. Однако я могу запросить окно, чтобы узнать текущее время в любое время.

Итак, чтобы дать более подробную информацию:

  1. Я запускаю работу на удаленной коробке
  2. Работа завершена
  3. Я иногда получаю отношение к выполнению задания
  4. Я конвертирую время в GMT

Если изменение времени (летнее время) происходит между 1. и 2. Я ввернут. Мое преобразование GMT ​​сломается. Я думаю, после 2) мне нужно получить текущее время удаленного ящика и посмотреть, есть ли разница> 58 минут, а затем применить это к преобразованию. Но я не могу найти надежный способ сделать это.


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");
}

Ответы [ 3 ]

2 голосов
/ 27 июня 2011

Очевидным надежным решением будет использование UTC (которое не имеет летнего времени) для отметки времени, которую вы отправляете.Использование любой системы времени, которая имеет присущую неоднозначность (каждый год существует один час наложения, когда вы можете получать одинаковые временные метки в разное время), сделает невозможным надежный метод, поскольку информация теряется.

Если у вас нет контроля над форматом времени, который отправляет удаленный компьютер, вы можете попытаться экстраполировать только ту информацию, которая у вас есть, например, если время окончания меньше времени начала, добавьте один час,Это снова вносит двусмысленность, если работа заняла больше часа, но, по крайней мере, время не сдвинется назад.

1 голос
/ 28 июня 2011

Получите местное время в UTC в начале и в конце удаленного задания. Получите время удаленного задания и перейдите к UTC в начале и в конце задания. Преобразуйте коллекцию «исторического» времени в GMT / UTC, как указано в вашем исходном сообщении. Храните эти данные вместе в структуре или классе и дайте дополнительное время начала ясного имени, такого как LocalDLSValidation и т. Д. Теперь мы должны проверить следующие сценарии:

  1. Start and end time delta between Local and Remote is within allowed threshold(50mins?)

Это золотой футляр. Никаких изменений не требуется для нашей коллекции исторических времен

 2. Local start/end time and remote time delta is outside threshold. 

Это второй самый простой случай. Это означает, что мы можем + или - час на всю нашу коллекцию раз.

 3.Local start time and remote time delta is within threshold.  But end is outside. 

Это наш худший сценарий, так как это означает, что изменения произошли в середине нашей работы. Если работа длится менее часа, тогда будет легко увидеть, сколько раз в нашей коллекции должно быть + или - один час.

Если оно больше 1 часа .... ммммм. Здесь мы сталкиваемся с проблемами.

   4.  Start time between local and remote is different but end time is different

В зависимости от варианта использования в OP это не должно происходить.

1 голос
/ 27 июня 2011

Изменение времени появляется два раза в год - зачем вам это беспокоить? Во всяком случае, вы не можете изменить формат времени, чтобы включить событие изменения времени? Или проверьте, выполняется ли задание во время изменения времени, сравнивая его с фиксированным временем и датой, когда появляется изменение времени?

...