20

Visual Studio c++ Compiler (2010) を使用していますが、ライブラリには ANSI C と POSIX ライブラリ関数の実装が異なります。

ANSI C 関数と Windows CRT 実装の違いは何ですか? たとえば、tzset()and _tzset()or setenv()ansの違いは何_setenv()ですか? 同じことを同じ方法で行うようです...

msvc (2010) を使用していますが、Windows CRT 実装を優先する必要がありますか?

編集1

UTC で表現された struct tm を移植可能な方法で変換したいのですがtime_t、それを行うための移植可能な方法はありません。さまざまなプラットフォーム (Android、Linux、Windows、Windows CE) 用の関数を作成する必要があります。

、およびを使用するこのstackoverflowの投稿を見ましたsetenvgetenvtzset

編集2

残念ながら、いくつかのテストの後getenv("TZ")、Windows で null ポインターを返すことがわかりました。しかし、なぜ UTC 時刻構造体を に変換するのがそれほど難しいのtime_tでしょうか?

編集 3

Boost から、boost/chrono/io/time_point_io.hpp でこのコードの断片を発見しました。これが私を助けることを願っています。

inline int32_t is_leap(int32_t year)
{
  if(year % 400 == 0)
  return 1;
  if(year % 100 == 0)
  return 0;
  if(year % 4 == 0)
  return 1;
  return 0;
}
inline int32_t days_from_0(int32_t year)
{
  year--;
  return 365 * year + (year / 400) - (year/100) + (year / 4);
}
inline int32_t days_from_1970(int32_t year)
{
  static const int days_from_0_to_1970 = days_from_0(1970);
  return days_from_0(year) - days_from_0_to_1970;
}
inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day)
{
  static const int32_t days[2][12] =
  {
    { 0,31,59,90,120,151,181,212,243,273,304,334},
    { 0,31,60,91,121,152,182,213,244,274,305,335}
  };
  return days[is_leap(year)][month-1] + day - 1;
}

inline time_t internal_timegm(std::tm const *t)
{
  int year = t->tm_year + 1900;
  int month = t->tm_mon;
  if(month > 11)
  {
    year += month/12;
    month %= 12;
  }
  else if(month < 0)
  {
    int years_diff = (-month + 11)/12;
    year -= years_diff;
    month+=12 * years_diff;
  }
  month++;
  int day = t->tm_mday;
  int day_of_year = days_from_1jan(year,month,day);
  int days_since_epoch = days_from_1970(year) + day_of_year;

  time_t seconds_in_day = 3600 * 24;
  time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;

  return result;
}
4

5 に答える 5

3

私が知っているほとんどの関数では、違いはありません。

名前のアンダースコアは、これらが標準の C 関数ではないことを強調するためにあります。AFAIK、 ANSI C には関数tzsetsetenv関数もありません。ほとんどの場合、他のオペレーティング システムからの移植性を支援するために MS CRT によって実装される POSIX 関数です。

しかし、彼らは POSIX 互換性を主張していません。それがアンダースコアの理由です。そのため、これらの関数について注意して MS のドキュメントを読む必要があります...そこには悪魔がいます!

于 2013-05-20T10:55:03.087 に答える
1

私の実装はtimegmウィンドウで動作しています。

time_t timegm(struct tm * a_tm)
{
    time_t ltime = mktime(a_tm);
    struct tm tm_val;
    gmtime_s(&tm_val, &ltime);
    int offset = (tm_val.tm_hour - a_tm->tm_hour);
    if (offset > 12)
    {
        offset = 24 - offset;
    }
    time_t utc = mktime(a_tm) - offset * 3600;
    return utc;
}

大丈夫なはずです。

于 2014-12-23T11:46:09.380 に答える