处理夏令时c++

Dealing with daylight savings C++

本文关键字:c++ 夏令时 处理      更新时间:2023-10-16

给定输入日期和时间(字符串格式),我试图使用ctime(如mktime)中给出的time函数获得历元时间。将time_t历元时间转换回日期和时间会得到比原始日期和时间少一个小时的日期和时间。我已经进行了一些讨论,说可能会有一个小时的调整,以适应夏令时。下面是代码:

//sample strptime program.
#include <iostream>
#include <ctime>
#include <string>
using namespace std;
long parseTime(string time) {
  cout << "Time entered = " << time << endl;
  long timeSinceEpoch;
  struct tm t;
  if(time.find("/") != string::npos) {
    //format of date is mm/dd/yyyy. followed by clock in hh:mm (24 hour clock).
    if(strptime(time.c_str(), "%m/%e/%Y %H:%M", &t) == NULL) {
      cout << "Error. Check string for formatting." << endl;
    }
  } else if(time.find("-") != string::npos) {
    //format of date is yyyy-mm-dd hh:mm:ss (hh in 24 hour clock format).
    cout << "I am here." << endl;
    if(strptime(time.c_str(), "%Y-%m-%e %H:%M:%S", &t) == NULL) {
      cout << "Error. Check string for formatting of new date." << endl;
    }
  }
  cout << "Details of the time structure:" << endl;
  cout << "Years since 1900 = " << t.tm_year << endl;
  cout << "Months since January = " << t.tm_mon << endl;
  cout << "Day of the month = " << t.tm_mday << endl;
  cout << "Hour = " << t.tm_hour << " Minute = " << t.tm_min << " second = " << t.tm_sec << endl;
  timeSinceEpoch = mktime(&t);
  time_t temp = mktime(&t);
  cout << "Time since epoch = " << timeSinceEpoch << endl;
  cout << "Reconverting to the time structure:" << endl;
  struct tm* t2 = localtime(&temp);
  cout << "Details of the time structure:" << endl;
  cout << "Years since 1900 = " << t2->tm_year << endl;
  cout << "Months since January = " << t2->tm_mon << endl;
  cout << "Day of the month = " << t2->tm_mday << endl;
  cout << "Hour = " << t2->tm_hour << " Minute = " << t2->tm_min << " second = " << t2->tm_sec << endl;
  return timeSinceEpoch;
}
int main(int argc, char *argv[]) {
  string date, t;
  cout << "Enter date: " << endl;
  cin >> date;
  cout << "Enter time: " << endl;
  cin >> t;
  struct tm time;
  string overall = date + " " + t;
  long result = parseTime(overall);
  cout << "Time in date + time = " << overall << " and since epoch = " << result << endl;
return 0;
}

麻烦的输入是:日期:2013-03-11时间:04:41:53

我的问题(s):
1. 检查tm_idst标志返回一个非零,表示夏令时生效。但是,我如何知道正在谈论的是哪个时区呢?
2. 上面给出的时间戳可能与我所在的时区不同。是否有一种方法来指定时区,以便正确设置tm_idst标志?
3.当我不确定时间戳记录在哪个时区时,我如何处理DST ?

普通的C++在时区数据上是非常稀疏的,如果没有要格式化的时间中的时区规范,那么在一些时期您将得到不一致的结果—例如时钟返回后的重复时间。这就是为什么总是建议在UTC中记录所有时间戳-即永远不要对记录的时间戳应用时区,用GMT记录它,然后将该值作为显示变量来回转换,您可以完全控制。

Linux/BSD有一些额外的字段可以用来确定时区,以及与UTC的偏移量-例如,在Linux上它是__tm_gmtoff字段,在BSD(/Mac OS X)中它称为tm_gmtoff

有一个额外的字段标记时区,在linux上是__tm_zone,在BSD(/Mac OS X)中是tm_zone,但该字段仅在获得localtime时填充。

我稍微修改了一下你的例子,得到了以下输出:

Time entered = 2013-04-05 15:00
I am here.
Error. Check string for formatting of new date.
Details of the time structure:
Years since 1900 = 113
Months since January = 3
Day of the month = 5
Hour = 15 Minute = 0 second = 0
gmtoff = 0
Time since epoch = 1365174000
Reconverting to the time structure:
Details of the time structure:
Years since 1900 = 113
Months since January = 3
Day of the month = 5
Hour = 16 Minute = 0 second = 0
gmtoff = 3600
Zone = IST
Time in date + time = 2013-04-05 15:00 and since epoch = 1365174000

如果你在Windows中使用这种结构,你将不得不使用另一种机制,尽管,因为它没有这两个额外的字段。