1

日時、ロケール、および夏時間が のような固定長の文字列として入力されるという要件がありYYMMDDHHMMCYます。凡例は以下に示されています。

  1. YY(年)
  2. MM(月)
  3. 日(日)
  4. HH(時)
  5. MM(分)
  6. タイムゾーン (中部は C、太平洋は P、山は M、東部は E)
  7. 夏時間 (夏時間が有効な場合は Y、そうでない場合は N)

必要なのは、指定されたタイムゾーンで時間を構築し、それを C/C++ でローカル タイムゾーンに変換する機能です。Boost は使用しません。要件を満たす既存の機能はありますか。私はstrptime、データをいくつかマッサージした後、それを使用できることを認識していますが、指定されたロケールで構造体を構築できる上記の関数があるかどうか疑問に思っています。

4

1 に答える 1

1

sscanf()orを使用strptime()して、ほとんどのフィールドを抽出します。タイムゾーン文字と DST 文字は、独自にデコードする必要があります。2 桁の年しか使用していないため、範囲を定義する必要があります。以下の例では、1970 年から 2069 年を使用しています。抽出されたタイムゾーン文字を使用して、通常のタイムゾーン名を形成します。を呼び出す前mktime()に、TZ をタイムゾーン名に設定します。次に、time_t手に持って、現地時間に変換します。

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

extern time_t mktime_TZ(struct tm *tm, const char *tz);
extern time_t DecodeTimeString_time_t(const char *time_string);

void DecodeTimeString_Local(const char *time_string, struct tm *local) {
  // Various error handling not shown
  time_t t;
  t = DecodeTimeString_time_t(time_string);
  *local = *localtime(&t);
}

time_t DecodeTimeString_time_t(const char *time_string /* YYMMDDHHMMCY */) {
    struct tm tm;
    char Zone, DST;
    int result = sscanf(time_string, "%2d%2d%2d%2d%2d%[CEMP]%[NY]",
        &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &Zone, &DST);
    if (result != 7) {
      ; // handle error
    }
    // Your need to decide how to handle 2 digits years
    // Assume 70-99 is 1970-1999 and 0 to 69 is 2000-2069
    if (tm.tm_year < 70) tm.tm_year += 2000-1900;
    tm.tm_mon--;  // Assume DateString used "01" for January, etc.
    tm.tm_sec = 0;
    tm.tm_isdst = Zone == 'Y';
    const char *TZ;
    switch (Zone) {
      case 'P':  TZ = "PST8PDT"; break;  // Pacific
      case 'M':  TZ = "MST7MDT"; break;  // mountain
      case 'C':  TZ = "CST6CDT"; break;  // central
      case 'E':  TZ = "EST5EDT"; break;  // eastern
    }
    time_t t = mktime_TZ(&tm, TZ);
    return t;
    }

// Form time_t from struct tm given a TZ
time_t mktime_TZ(struct tm *tm, const char *tz) {
  time_t t;
  const char *old_tz = getenv("TZ");
  if (setenv("TZ", tz, 1 /* overwrite */)) {
    return -1; // handle error
  }
  tzset();
  t = mktime(tm);
  if (old_tz) {
    if (setenv("TZ", old_tz, 1 /* overwrite */)) {
      return -1; // handle error
    }
  }
  else {
    if (unsetenv("TZ")) {
      return -1; // handle error
    }
  }
  tzset();
  return t;
}
于 2013-06-26T02:37:50.860 に答える