5

ローカルの日付/時刻を含む文字列があり、それを time_t 値 (UTC) に変換する必要があります-これを試してみました:

char* date = "2009/09/01/00";
struct tm cal = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL};
strptime(date, "%Y/%m/%d/%H", &cal);
time_t t = mktime(&cal);

しかし、返される time_t 値は、文字列がローカル時間ではなく UTC として解析された場合に期待される値です。strptime が何をすべきかを誤解しているかもしれませんが、9 月 1 日の私のタイムゾーン (英国) では BST (つまり、UTC + 1 時間) を使用しているため、最終的に得られる値は UTC より 1 時間進んでいると予想されます。 .

その日付に有効であった UTC オフセットを自動的に考慮して、文字列を現地時間として解釈する方法はありますか? struct tm ではなく time_t 値が必要であることに注意してください。上記の例では、time_t 値を 2009-09-01 01:00:00 GMT に対応させたいと考えています。

4

3 に答える 3

6

mktimeローカルタイムゾーンで構造体tmを解釈するために使用できます。tm_isdstその際、フラグの設定には注意が必要です。夏は0、冬は1、計算するには-1になりmktimeます。次にいくつかのサンプルコードを示します。

void main()
{
    char* date = "2009/09/01/00";
    struct tm cal = {};
    // Read string into struct tm
    strptime(date, "%Y/%m/%d/%H", &cal);
    // Tell mktime to figure out the daylight saving time
    cal.tm_isdst = -1;
    printf("%20s: %s", "Before mktime", asctime(&cal));
    // Convert struct tm to time_t
    time_t t = mktime(&cal);
    // Convert time_t to localtime
    struct tm localcal = *localtime(&t);
    printf("%20s: %s", "Local time", asctime(&localcal));
    printf("%20s: %i\n", "Local DST", localcal.tm_isdst);
    // Convert time_t to GMT
    struct tm gmcal = *gmtime(&t);
    printf("%20s: %s", "GM time", asctime(&gmcal));
    printf("%20s: %i\n", "GM DST", gmcal.tm_isdst);
}

これは印刷されます(私はGMT + 1に住んでいて、今は冬です):

   Before mktime: Tue Sep  1 00:00:00 2009
      Local time: Tue Sep  1 00:00:00 2009
       Local DST: 1
         GM time: Mon Aug 31 22:00:00 2009
          GM DST: 0

mktime現在の夏時間に基づいて9月の日付を変換しているようです。今は11月なので、実際には1時間の休みです。私はそれを修正する方法を見つけていません。

于 2009-11-19T17:05:38.280 に答える
0

Andomar のおかげで、私は今それをクラックしたと思います - このコードは私が必要とすることを行い、現在の DST ステータスに関係なく動作するように見えます (これを確認するために PC の時計を変更しました):

#include <time.h>
#include <assert.h>

time_t parseLocalDate(char* date){
    struct tm cal = {0, 0, 0, 0, 0, 0, 0, 0, -1, 0, NULL};
    strptime(date, "%Y/%m/%d/%H", &cal);
    return mktime(&cal);
}

int main(int argc, char *argv[]){
 // DST is effect, Local Time = GMT+1
    assert(1251759600 == parseLocalDate("2009/09/01/00")); // Mon, 31 Aug 2009 23:00:00 GMT
    assert(1254351600 == parseLocalDate("2009/10/01/00")); // Wed, 30 Sep 2009 23:00:00 GMT
 // DST not in effect, Local Time = GMT
    assert(1257033600 == parseLocalDate("2009/11/01/00")); // Sun, 01 Nov 2009 00:00:00 GMT
}
于 2009-11-20T08:49:35.290 に答える
0

を使用した私のバージョンは次のとおりtm_gmtoffです。願わくば、図書館が夏時間に対応してくれることを願っています...

#define _BSD_SOURCE
#define _XOPEN_SOURCE
#include <stdio.h>
#include <time.h>

int gmtoffset(void) {
  struct tm *dummy;
  time_t t = 0;
  dummy = localtime(&t);
  return dummy->tm_gmtoff; /* _BSD_SOURCE */
}

int main(void) {
  int off;
  const char *date = "2009/09/01/00";
  struct tm cal = {0};
  time_t t;

  off = gmtoffset();

  strptime(date, "%Y/%m/%d/%H", &cal); /* _XOPEN_SOURCE */
  t = mktime(&cal);
  printf("t     --> %s", ctime(&t)); /* ctime includes a final '\n' */
  t -= off;
  printf("t-off --> %s", ctime(&t));
  return 0;
}
$ /usr/bin/gcc ptime.c
$ ./a.out
t --> 2009 年 9 月 1 日火曜日 01:00:00
t-off --> 2009 年 9 月 1 日火曜日 00:00:00
于 2009-11-19T19:02:35.753 に答える