首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何向从time()获取的时间添加一天

如何向从time()获取的时间添加一天
EN

Stack Overflow用户
提问于 2008-11-21 22:03:32
回答 3查看 43.6K关注 0票数 20

我有一个时间,表示为自1970年1月1日午夜( UTC )以来经过的秒数(先前调用time ()的结果)。我该如何增加一天的时间呢?

添加24 * 60 * 60在大多数情况下都有效,但如果夏令时在两者之间打开或关闭,则会失败。换句话说,我主要想增加24小时,但有时是23或25小时。

为了说明-该程序:

代码语言:javascript
复制
#include <time.h>
#include <iostream>

int main()
{
  time_t base = 1142085600;
  for(int i = 0; i < 4; ++i) {
    time_t time = base + i * 24 * 60 * 60;
    std::cout << ctime(&time);
  }
  return 0;

}

产生:

代码语言:javascript
复制
Sat Mar 11 08:00:00 2006
Sun Mar 12 09:00:00 2006
Mon Mar 13 09:00:00 2006
Tue Mar 14 09:00:00 2006

我想要3月12日,13日的《纽约时报》...也是上午8点

FigBug提供的答案给我指明了正确的方向。但我不得不使用localtime而不是gmtime。

代码语言:javascript
复制
int main()
{
  time_t base = 1142085600;
  for(int i = 0; i < 4; ++i) {
    struct tm* tm = localtime(&base);
    tm->tm_mday += i;
    std::cout << asctime(tm);
 }
 return 0;
}

给我:

代码语言:javascript
复制
Sat Mar 11 08:00:00 2006
Sat Mar 12 08:00:00 2006
Sat Mar 13 08:00:00 2006
Sat Mar 14 08:00:00 2006

这就是我想要的。使用gmtime可以得到14:00:00的时间

但是,请注意,所有的日子都是星期六。如果我抛出mktime函数,我又回到了开始的地方:

代码语言:javascript
复制
#include <time.h>
#include <iostream>

int main()
{
  time_t base = 1142085600;
  for(int i = 0; i < 4; ++i) {
    struct tm* tm = localtime(&base);
    tm->tm_mday += i;
    time_t time = mktime(tm);
    std::cout << asctime(tm);
 }
 return 0;
}

给了我:

代码语言:javascript
复制
Sat Mar 11 08:00:00 2006
Sun Mar 12 09:00:00 2006
Mon Mar 13 09:00:00 2006
Tue Mar 14 09:00:00 2006

我错过了什么?

好的,我已经尝试了FigBug的最新建议,即使用:

代码语言:javascript
复制
 std::cout << ctime(&time);

而不是递增时间,但我得到了相同的结果。所以我猜我的库和/或编译器搞得一团糟。我在cygwin上使用的是g++ 3.4.4。我将文件复制到Solaris5.8上,并在那里使用g++ 3.3进行编译。我在那里得到了正确的结果!实际上,无论我使用ctime还是asctime进行输出,我都会得到正确的结果:

代码语言:javascript
复制
Sat Mar 11 08:00:00 2006
Sun Mar 12 08:00:00 2006
Mon Mar 13 08:00:00 2006
Tue Mar 14 08:00:00 2006

在带有g++ 3.4.6的Red Hut Linux上,我也得到了正确的结果(使用两个输出函数)。

所以我猜我遇到了一个Cygwin bug。

感谢您的帮助和建议...

EN

回答 3

Stack Overflow用户

发布于 2008-11-21 22:13:38

只需添加24*60*60即可。它应该不会在DST期间失败,因为UTC永远不会使用DST。

如果它失败了,那么您在代码中的某个地方就没有使用UTC。删除时区依赖关系。

票数 4
EN

Stack Overflow用户

发布于 2008-11-21 22:06:28

当你想要显示值时,我总是有最好的结果,保持时间戳UTC,并将它们转换为指定的时区(包括夏令时)。

这就省去了很多这样的麻烦(并且使你的程序独立于时区。

票数 3
EN

Stack Overflow用户

发布于 2016-05-31 00:30:50

一个非常古老的问题的新答案。

新答案的理论基础:现在有更好的工具来解决这个问题,使结果更不容易出错,更容易阅读,并且通过最小化串行<->字段转换实际上更有效。

新的答案需要C++11/14、<chrono>和这个free, open source, timezone library

代码如下:

代码语言:javascript
复制
#include "tz.h"
#include <iostream>

int
main()
{
    using namespace std::chrono;
    using namespace date;
    auto base = make_zoned("Pacific/Easter", sys_seconds{1142085600s});
    for (int i = 0; i < 4; ++i)
    {
        std::cout << format("%a %b %d %T %Y %Z", base) << '\n';
        base = base.get_local_time() + days{1};
    }
}

首先创建一个zoned_time,将所需的时区与Unix时间戳配对。

它被格式化为任何所需的格式。

1天的增加是在时区的本地时间系统中完成的,这将考虑到夏令时。输出为:

代码语言:javascript
复制
Sat Mar 11 09:00:00 2006 -05
Sun Mar 12 09:00:00 2006 -06
Mon Mar 13 09:00:00 2006 -06
Tue Mar 14 09:00:00 2006 -06

事实证明,这个输出并不完全是OP所说的他想要的(请求的输出是每天08:00:00 )。然而,我使用这个库来充分研究整个星球在这一日期的时间转换。只有一个时区在这一天发生了转换:太平洋/复活节。这个过渡是向后移动一个小时,而不是向前移动。这是智利使用的时区,在南半球,人们会回到三月份的时间范围内。

这可以通过使用UTC而不是本地时间进行算术来演示。这是对上面一行程序的微小调整:

代码语言:javascript
复制
        base = base.get_sys_time() + days{1};

使用base.get_sys_time()而不是base.get_local_time(),会导致运算在“系统时间”内完成,即国际协调时忽略闰秒。现在,输出更改为:

代码语言:javascript
复制
Sat Mar 11 09:00:00 2006 -05
Sun Mar 12 08:00:00 2006 -06
Mon Mar 13 08:00:00 2006 -06
Tue Mar 14 08:00:00 2006 -06
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/310363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档