给定一个输入日期和时间(字符串格式),我试图使用time中提供的ctime函数(例如mktime)来获取其时间。将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

我的问题:
1.检查tm_idst标志返回非零值,表示DST生效。但是,我怎么知道正在谈论哪个时区?
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,但是只有在获取本地时间时才会填充该字段。

我稍微修改了您的示例,并得到以下输出:

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中使用此结构,则必须使用另一种机制,因为它没有这两个额外的字段。

09-18 02:35