これは私のコードです。
#include <time.h>
#include <stdio.h>
time_t my_timegm (struct tm *tm, char *tz_offset);
int
main (void)
{
struct tm time_tm;
time_t start_timet, end_timet;
time_tm.tm_sec = 0;
time_tm.tm_min = 0;
time_tm.tm_hour = 0;
time_tm.tm_mday = 1;
time_tm.tm_mon = 0;
time_tm.tm_year = 2023 - 1900;
time_tm.tm_isdst = -1;
start_timet = my_timegm (&time_tm, "Etc/GMT-6");
printf ("\n%li ", start_timet);
start_timet = my_timegm (&time_tm, "America/Chicago");
printf ("\n%li ", start_timet);
}
my_timegmは
#include <time.h>
#include <stdlib.h>
time_t
my_timegm (struct tm *tm, char *tz_offset)
{
time_t ret;
char *tz;
tz = getenv ("TZ");
setenv ("TZ", tz_offset, 1);
tzset ();
ret = mktime (tm);
if (tz)
setenv ("TZ", tz, 1);
else
unsetenv ("TZ");
tzset ();
return ret;
}
出力は次のとおりです
1672509600
1672552800
43200秒(12時間)の違いがあるのはなぜですか?または、GMT-6がAmerica / Chicago(UTC-6)と異なるのはなぜですか?
答え1
POSIXを責めなさい。
環境変数の POSIX 仕様がTZ
最初に作成されたとき、正のタイムゾーン番号が西半球のタイムゾーンに割り当てられました。これは、おそらく、さまざまなUnixシステム開発者の間の既存の慣行から到達できる唯一の合意でした。ほとんどはまたはすべて当時アメリカ本土に基づいていたので、迷惑なマイナス記号を自分の分野で使用したくありませんでした。
デフォルトではタイムTZ=xxx-6
ゾーンスタンプが指定されており、xxx
現地時間から6時間を減算するとUTCを取得できます。
データベースzoneinfo
(一時Olson タイムゾーンデータベース、現在IANAによって管理されていますEtc/GMTxx
) は、レガシー互換性のためにタイムゾーンに同じ表記規則を使用します。
$ TZ=GMT-6 date # legacy POSIX
Sun 11 Jun 10:23:18 GMT 2023 # note: GMT is a lie here!
$ TZ=Etc/GMT-6 date # modern zoneinfo form
Sun 11 Jun 10:23:25 +06 2023
$ TZ=GMT6 date # legacy POSIX
Sat 10 Jun 22:24:31 GMT 2023 # note: GMT is a lie here!
TZ=Etc/GMT+6 date # modern zoneinfo form
Sat 10 Jun 22:24:35 -06 2023
この形式を使用すると、zoneinfo
タイムスタンプ(+06
または-06
)で表示されるUTCオフセットには、タイムゾーン名に期待されるものとは反対の符号が付きますzoneinfo
。
答え2
「硬度を求めて15で割ってオフセットとして使いたい」
ここに間違いがあります。この推論によれば、GMT領域は0時から15時まで西に拡張し、他の領域は15時から30時、30時から45時などに拡張する必要があります。
しかし、GMTタイムゾーンは、東京7.5度から西経7.5まで拡張されます。したがって、西の次の領域は7.5wから22.5w、次に22.5wから37.5wなどです。
これは、あなたが見つけた12時間の違いを説明していませんが、必要な計算に誤差があることを指摘しています。
答え3
私は文で答えを見つけました。日付tzは変換にGMTを使用し、同じGMTを使用する都市名は異なる結果を提供します。これは、GMT-xが実際にGMTよりx時間速いことを示します。これは私のコードで確認されました。
int
main (void)
{
struct tm time_tm;
time_t start_timet, end_timet;
time_tm.tm_sec = 0;
time_tm.tm_min = 0;
time_tm.tm_hour = 0;
time_tm.tm_mday = 1;
time_tm.tm_mon = 0;
time_tm.tm_year = 2023 - 1900;
time_tm.tm_isdst = 0;
start_timet = my_timegm (&time_tm, "America/Chicago");
printf ("\n%li ", start_timet);
time_tm.tm_isdst = 0;
start_timet = my_timegm (&time_tm, "Etc/GMT+6");
printf ("\n%li ", start_timet);
}