[英]Getting DST for negative `time_t` in MSVC
我試圖確定給定時區的DST中是否有給定的time_t
值。 所以我寫了類似下面的東西:
inline bool is_DST(time_t t) {
struct tm* ti = localtime(&t);
return ti->tm_isdst > 0;
}
這對於當前的時代很有用。 例如,在當前的time_t值上,它返回true
。 對於J2000時期,它返回false
。 尼斯。
不幸的是, localtime(...)
的MSVC變體在負輸入上返回nullptr
。 閱讀上面鏈接的文檔會告訴我,它也將在3000年后失敗。因此,例如(time_t)(-1)
(對應於1969-12-31 23:59:59)將導致段錯誤。
這不好。 1969年不久。 標准做法是假設1972年之前或將來的任何地方都沒有leap秒來推斷UTC(直到宣布)。 *
根據上述推論,實現is_DST(...)
適用於64位time_t
給定的日期范圍(±2.9 * 10 11年左右)時,我有哪些選擇?
* 關於這是否正確,存在一些疑問。 seconds秒是在1972年引入的,向后外推UTC意味着您必須假設沒有leap秒(應該是)。 而且,將UTC向前推算也很困難,因為地球的自轉使seconds秒變得不可預測。
這是ildjarn在評論中引用的庫:
https://github.com/HowardHinnant/date
它是開源的,適用於VS-2013及更高版本。 這是使用它來實現is_DST
:
#include "tz.h"
#include <ctime>
bool
is_DST(std::time_t t)
{
using namespace std::chrono;
using namespace date;
return current_zone()->get_info(system_clock::from_time_t(t)).save != 0min;
}
這將對負time_t
,但不適用於64位time_t
的整個范圍(這將是+/- 2,920億年)。 但是它很容易回到最初引入統一時間的1800年代中期。
在Windows上,您將必須安裝libcurl或手動下載IANA時區數據庫 。
如果您想在除計算機當前時間段以外的某個時區回答此問題,那很容易:
return locate_zone("Europe/Monaco")
->get_info(system_clock::from_time_t(t)).save != 0min;
Windows上的范圍是[-27258-04-19 21:11:54.5224192, 31197-09-14 02:48:05.4775807]
。 此范圍的限制是,這是VS system_clock::time_point
的范圍(精度為100ns,並存儲為int64_t
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.