【问题标题】:Convert historical time to GMT将历史时间转换为 GMT
【发布时间】:2011-09-23 10:28:09
【问题描述】:

我需要将“2011061411322100”格式的一些字符串时间转换为 GMT - 我的第一次尝试如下。然而,问题是时代来自另一台PC,是一个历史时期。所以我没有实时获得时间,所以我不能简单地从我的代码正在运行的盒子上的当地时间获取格林威治标准时间。

问题是,如果我的代码在时间更改期间运行,时间更改将发生在我的盒子上,而不是在我获取时间的远程盒子上。但是,我可以随时查询该框以获取当前时间。

所以,提供更多细节:

  1. 我在远程机器上开始工作
  2. 作业完成
  3. 我遇到了一些与正在运行的作业相关的时间
  4. 我将时间转换为 GMT

如果在 1. 和 2. 之间发生时间变化(夏令时),我就完蛋了。我的 GMT 转换将中断。我想在 2)之后我需要获取当前的 Remote Box 时间,看看是否有 > 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");
}

【问题讨论】:

    标签: c++ gmt ctime


    【解决方案1】:

    显而易见的可靠解决方案是使用 UTC(没有夏令时)作为您发送的时间戳。使用任何具有固有模糊性的时间系统(每年有一个小时的重叠,您可以在不同的时间获得相同的时间戳),因为信息丢失,所以不可能有一个万无一失的方法。

    如果您无法控制远程机器发送的时间格式,您只能尝试根据您拥有的信息进行推断,例如,如果结束时间低于开始时间,则添加一小时.如果工作花费的时间超过一小时,这会再次引入歧义,但至少时间不会倒退。

    【讨论】:

    • 不幸的是,我必须以 GMT 格式发送
    • 浏览文档(msdn:msdn.microsoft.com/en-us/library/0z9czt0w(v=vs.80).aspx),gmtime 的输入和输出似乎都应该是 UTC。这基本上是没有夏令时的 GMT(tm_isdst 始终为零)。
    • 没有格林威治标准时间。至少不再是,自 1974 年以来不再如此。有些术语在被弃用后往往会持续很长时间,而 GMT 就是其中之一。最简单的解决方案是假设 GMT 表示 UTC,正如 Aaldert 建议的那样。
    • 感谢您的澄清。这仍然留下了处理远程机器时间的问题。
    • 由于您可以获得远程机器的当前时间,如果您在调度作业之前和完成之后执行此操作,并将其与本地机器上经过的时间进行比较(为了更好的衡量,应该是忽略为此特定目的的本地 DST 更改),您至少可以推断出在作业期间远程计算机上是否启动了夏令时事件。如果它们在任一方向上相差大约一个小时(58 分钟应该可以工作,但 45 应该一样好),您可以相应地处理它。
    【解决方案2】:

    时间变化一年出现两次 - 为什么要打扰?无论如何,您不能更改时间格式以包含时间更改事件吗?或者通过比较出现时间变化的某个固定时间和日期来检查工作是否在时间变化期间完成?

    【讨论】:

    • 它只发生两次,但会一直出错,直到远程盒子上发生时间变化...
    【解决方案3】:

    获取远程作业开始和结束时的 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 小时....mmmmm。这就是我们遇到问题的地方。

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

    根据 OP 中的用例,这不应该发生。

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 2018-06-28
      • 2017-08-26
      • 2012-12-25
      • 2011-09-24
      • 2013-10-29
      • 2021-10-02
      相关资源
      最近更新 更多