在C ++中将unix时间戳转换为星期几?

时间:2016-11-14 07:48:09

标签: c++ datetime-conversion

如何根据任意Unix时间戳(秒)确定加利福尼亚州(太平洋时间)的星期几?我一直在搜索,但还没有找到C ++的内置库。

UTC通常比PT提前8小时,但只是从Unix时间戳减去8小时,并且创建tm结构不起作用,因为这可以减少夏令时的细微差别。

3 个答案:

答案 0 :(得分:9)

以下是使用Howard Hinnant's date library的方法。这是一个基于<chrono>的免费的MIT许可C ++ 11/14库:

#include "tz.h"
#include <iostream>

int
main()
{
    using namespace std::chrono_literals;
    using namespace date;
    auto unix_timestamp = sys_seconds{1479664467s};
    auto zt = make_zoned("America/Los_Angeles", unix_timestamp);
    auto wd = weekday{floor<days>(zt.get_local_time())};
    std::cout << wd << '\n';
}

第一行只构造unix时间戳(你可以从其他来源获得)。在C ++ 11中,我们没有chrono-literals,所以这一行代之以:

auto unix_timestamp = sys_seconds{seconds{1479664467}};

make_zoned()根据zoned_time<seconds>unix_timestamp“America / Los_Angeles”创建time_zonezoned_timetime_zone和unix时间戳的集合。

您可以使用zoned_time获取zt.get_local_time()的当地时间。这是chrono::time_point,但没有与之关联的时钟。此时间点的精度将等于原始时间戳的精度(在这种情况下为秒)。

您可以通过将local_time缩减为local_time的精度来获取days的当周某一天:

floor<days>(zt.get_local_time())

此日精度time_point将转换为weekday类型。

可以打印weekday,参与weekday算术和比较,或明确转换为[0,6]范围内的unsigned

上述程序输出:

Sun

此库的时区部分是IANA timezone database的忠实代表。它将在当地时区和UTC之间进行正确的调整,直到1800年代中期到现在。如果您在1800年代中期之前传递库时间戳,则最早的已知UTC偏移量会向后推断到-32768年。您还可以将未来的时间戳传递给32767年,并且当前的偏移和夏令时规则将向前传播。

由于此库是基于<chrono>构建的,因此它将处理<chrono>提供的任何精度。请注意,某些chrono::duration(如nanoseconds的范围更为有限(nanoseconds为+/- 292年)。

库/进程是线程安全的。也就是说,程序可以直接使用您指定的任何时区,而无需更改计算机的时区或环境变量。它也不涉及C时序API的一部分,由于非const函数局部静态,已知它不是线程安全的。

移植到最近版本的gcc,clang和VS。

答案 1 :(得分:2)

使用标准UNIX C(非线程安全版)的Hacky方式:

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

void print_times() {
  char my_buf[100];
  time_t now = time(NULL);
  printf(ctime(&now));
  strftime(my_buf, 100, "DoW=%w Tz=%Z\n", localtime(&now));
  printf(my_buf);
}

int main( int argc, char * argv[] ) {
  print_times();
  setenv("TZ", "America/Los_Angeles", 1);
  print_times();
  unsetenv("TZ");
  print_times();
}

不幸的是,TZ env var或更改文件/etc/localtime是影响UNIX时间函数的时区设置的唯一方法(引擎盖下tzset()使用这些来源初始化一组共享变量,用于编码所有库函数的时区设置。)

问题是您需要为您需要的区域提供UNIX TZ字符串。 zoneinfo格式是最简单和推荐的格式。我使用tzselect生成太平洋时间的TZ值。

有关标准UNIX时区设置的信息,另请参阅man 5 localtimeman tzselect

答案 2 :(得分:1)

你可以使用Boost库吗? 如果您可以找出Posix时区字符串(IEEE Std 1003.1,请参阅http://www.boost.org/doc/libs/1_62_0/doc/html/date_time/local_time.html#date_time.local_time.posix_time_zone)了解您的时区(PST),那么下面的示例可能有所帮助。

$(document).ready(function() {

  $(".checkbox").on("change", ".item", function() {
    alert('event');
    if (this.checked) {
      alert('post');
      $.post('load.php', {
        name: name
      }, function(data) {
        $('#name-data').html(data);
      });

    }
  });
});