如何根據任意Unix時間戳(秒)來確定加利福尼亞州(太平洋時間)一週中的哪一天?我已經搜索過,但還沒有找到C++的內置庫。將C++中的unix時間戳轉換爲星期幾?
UTC通常比PT早8小時,但是從Unix時間戳簡單地減去8小時並創建tm
結構不起作用,因爲這會折扣日光節約細微差別。
如何根據任意Unix時間戳(秒)來確定加利福尼亞州(太平洋時間)一週中的哪一天?我已經搜索過,但還沒有找到C++的內置庫。將C++中的unix時間戳轉換爲星期幾?
UTC通常比PT早8小時,但是從Unix時間戳簡單地減去8小時並創建tm
結構不起作用,因爲這會折扣日光節約細微差別。
以下是使用Howard Hinnant's date library的方法。這是一種基於<chrono>
自由MIT許可C++十四分之十一庫:
#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我們沒有計時,文字等這條線將改爲:
auto unix_timestamp = sys_seconds{seconds{1479664467}};
make_zoned()
創建一個基於unix_timestamp
和time_zone
「美國/洛杉磯」一zoned_time<seconds>
。 A zoned_time
是time_zone
和unix時間戳的集合。
您可以使用zt.get_local_time()
從zoned_time
中獲取當地時間。這是一個chrono::time_point
,但沒有與之關聯的時鐘。這個時間點的精確度將等於您原始時間戳的精確度(在這種情況下爲秒)。
您可以通過截斷local_time
到days
精度得到local_time
的一週的當地日:
floor<days>(zt.get_local_time())
這一天精密time_point
將轉換成鍵入weekday
。
A 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.
你可以使用Boost庫嗎? 如果您可以找出時區(PST)的Posix時區字符串(IEEE標準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),那麼下面的示例可能會有所幫助。
#include <iostream>
#include <ctime>
#include <boost/date_time.hpp>
int main(int argc, char ** argv)
{
std::string posix_time_zone_string = "EST-05:00:00"; // you need to change this to the posix time representation of your desired timezone
time_t unix_time = 1479641855; //1479641855 = Sun, 20 Nov 2016 11:37:35 GMT
boost::posix_time::ptime pt = boost::posix_time::from_time_t(unix_time);
std::cout << "time in UTC: " << boost::posix_time::to_iso_extended_string(pt) << std::endl;
boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone(posix_time_zone_string));
boost::local_time::local_date_time dt_with_zone(pt, zone);
std::cout << "time in local timezone: " << boost::posix_time::to_iso_extended_string(dt_with_zone.local_time()) << std::endl;
// Get the week day (alternative 1)
std::cout << "local week day integer: " << boost::local_time::to_tm(dt_with_zone).tm_wday << std::endl; // 0=sunday, 1=monday, etc.
// Get the week day (alternative 2)
std::cout << "local week day name: " << dt_with_zone.local_time().date().day_of_week() << std::endl;
std::cout << "local week day integer: " << int(dt_with_zone.local_time().date().day_of_week()) << std::endl;
return 0;
}
使用標準的UNIX C(非線程安全版本)哈克的方式:
#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
的環境變量或更改文件/etc/localtime
是唯一的方法可以實現爲UNIX時間功能的時區設置(在引擎蓋tzset()使用這些源來初始化一組共享變量,這些變量對所有庫函數的時區設置進行編碼)。
一個問題是,您需要爲UNIX(TZ)字符串提供所需的區域。格式是最簡單並且推薦使用的格式。我用tzselect
爲太平洋時間生成TZ值。
有關標準UNIX時區設置的信息,另請參閱man 5 localtime
,man tzselect
。
我沒有downvote你,但如何['std :: localtime'](http://en.cppreference.com/w/cpp/chrono/c/localtime)? – Danh
謝謝 - 如果當地時間對我來說不是PT呢? –
[strftime](http://en.cppreference.com/w/cpp/chrono/c/strftime)。或[time_put](http://en.cppreference.com/w/cpp/locale/time_put)。或[霍華德Hinnant的日期](https://github.com/HowardHinnant/date) - 指針,而不是答案,這是爲什麼評論。 –