关于处理夏令时:处理夏令时 – C ++

Dealing with daylight savings time - C++

给定输入日期和时间(以字符串格式),我试图使用ctime中给出的time函数来获取它的纪元时间,如mktime。 将time_t纪元时间转换回日期和时间会导致日期和时间比原始时间小1小时。 我已经进行了一些讨论,说明在夏令时的情况下可能会调整一小时。 这是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//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,但该字段仅在您获得本地时间时填充。

我略微改变了你的例子,得到了以下输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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中使用这种结构,你将不得不使用另一种机制,因为它没有这两个额外的字段。