簡體   English   中英

在MSVC中獲取DST以獲取否定的“ time_t”

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM