在 C 中,函式 mktime() 根據本地時區回傳紀元時間(輸入結構是本地格式化的)。
函式 timegm() 根據 UTC 時間回傳紀元時間(輸入結構基于 UTC 時間格式化)。
函式 localtime_r () 接受一個紀元時間并回傳一個本地時區格式的結構。
函式 gmtime_r () 接受一個紀元時間并回傳一個 UTC 格式的結構。
我需要確定非本地時區當前是否是夏令時,如果它是本地的,它將與 localtime_r() 函式一起使用,但如果它不是本地的呢?
gmtime_r() 函式始終將 tm_isdst 欄位設定為零,這在此處不起作用。
也許還有其他一些我不知道的功能。沒有把握。
uj5u.com熱心網友回復:
如果您 (a) 不想亂用全域環境變數,并且 (b) 有“NetBSD 啟發”的時間函式可供您使用,那么還有一種可能性:mktime_z()and localtime_rz(),它可以讓您明確指定您想要的區域采用。因此,您不僅限于默認本地區域或 UTC。
這是一個例子:
int main(int argc, char **argv)
{
timezone_t tzp = tzalloc(argv[1]);
if(tzp == NULL) return 1;
time_t now = time(NULL);
struct tm tm;
struct tm *tmp = localtime_rz(tzp, &now, &tm);
char tmpbuf[20];
strftime(tmpbuf, sizeof(tmpbuf), "%H:%M:%S", tmp);
printf("right now in zone %s is %s\n", argv[1], tmpbuf);
tm.tm_year = 1976 - 1900;
tm.tm_mon = 7 - 1;
tm.tm_mday = 4;
tm.tm_hour = 12;
tm.tm_min = tm.tm_sec = 0;
tm.tm_isdst = -1;
time_t t = mktime_z(tzp, &tm);
printf("in zone %s, %d-d-d %d:d was %ld\n", argv[1],
1900 tm.tm_year, tm.tm_mon 1, tm.tm_mday, tm.tm_hour, tm.tm_min, t);
}
當我呼叫時,tzt America/New_York我看到
right now in zone America/New_York is 11:58:23
in zone America/New_York, 1976-07-04 12:00 was 205344000
當我呼叫時,tzt America/Los_Angeles我看到
right now in zone America/Los_Angeles is 08:58:49
in zone America/Los_Angeles, 1976-07-04 12:00 was 205354800
現在,話雖如此,還有兩條與我開頭的“如果”相關的評論:
一種。如果你不想亂用全域環境變數,我一點也不怪你。我非常討厭使用全域變數(更不用說環境變數)來影響函式的mktime行為localtime方式。然而,不幸的是,在這種情況下,在 C 語言中,這是推薦的方式。
灣。不幸的是,您實際上并沒有“讓您可以使用受 NetBSD 啟發的時間函式”的可能性很大。它們是非標準的,甚至不是很受歡迎。我之所以能夠編譯上面的測驗程式,只是因為我手頭有IANA tz 資料庫及其代碼的副本,如果您還定義了NETBSD_INSPIRED. (這就是為什么我違反了規則并且沒有展示一個完整的例子,所有的#include行,因為我的很奇怪和特殊。)
uj5u.com熱心網友回復:
這是我十年前寫的一些代碼,它符合ikegami在他們的回答中建議的內容:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
static void time_convert(time_t t0, char const *tz_value)
{
char old_tz[64] = "-none-";
char *tz = getenv("TZ");
if (tz != 0)
strcpy(old_tz, tz);
setenv("TZ", tz_value, 1);
tzset();
char new_tz[64];
strcpy(new_tz, getenv("TZ"));
char buffer[64];
struct tm *lt = localtime(&t0);
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", lt);
if (strcmp(old_tz, "-none-") == 0)
unsetenv("TZ");
else
setenv("TZ", old_tz, 1);
tzset();
printf("%lld = %s (TZ=%s, DST = %d)\n",
(long long)t0, buffer, new_tz, lt->tm_isdst);
}
int main(void)
{
time_t t0 = time(0);
char *tz = getenv("TZ");
if (tz != 0)
time_convert(t0, tz);
time_convert(t0, "UTC0");
time_convert(t0, "IST-5:30");
time_convert(t0, "EST5");
time_convert(t0, "EST5EDT");
time_convert(t0, "PST8");
time_convert(t0, "PST8PDT");
}
我得到的輸出是:
1650647033 = 2022-04-22 17:03:53 (TZ=UTC0, DST = 0)
1650647033 = 2022-04-22 22:33:53 (TZ=IST-5:30, DST = 0)
1650647033 = 2022-04-22 12:03:53 (TZ=EST5, DST = 0)
1650647033 = 2022-04-22 13:03:53 (TZ=EST5EDT, DST = 1)
1650647033 = 2022-04-22 09:03:53 (TZ=PST8, DST = 0)
1650647033 = 2022-04-22 10:03:53 (TZ=PST8PDT, DST = 1)
請注意,某些時區是在沒有夏令時的情況下指定的,并且代碼會報告DST = 0這些時區。
小心在多執行緒應用程式中像這樣更改時區。并且在重置環境時要小心,以防您fork()和exec()其他程式的 TZ 環境變數具有意外值。
注意:我已將代碼修改為:
- 使用
long long而不是long列印time_t值。令人討厭的事情之一是沒有標準的格式字串用于將time_t型別列印為整數(實際上,C 標準甚至不保證型別是整數,但它實際上在大多數系統上,并且 POSIX 需要它成為整數型別 — 參見<sys/types.h>)。此更改應允許 32 位系統在 2038 年作業。假設它time_t是 64 位值,即使它是 32 位系統;如果系統仍然使用 32-bit ,則在環繞到 -2 31time_t時它會被最終破壞- 但這不應該仍然是我的問題。time_t - 列印
lt->tm_isdst問題中想要的資訊。
uj5u.com熱心網友回復:
我需要確定非本地時區當前是否為夏令時
time_t從獲取當前時間time。- 使用將 env var 設定
TZ為目標時區putenv。 - 打電話
tzset。(我不知道這是否是必需的,但呼叫它肯定沒有壞處。) - 用于根據(修改后的)本地時區
localtime將 轉換time_t為 a 。struct tm - 檢查那個
tm_isdst欄位struct tm。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/462111.html
上一篇:大數序列的總和
