3

負のタイムスタンプがあります(つまり、1970年より古い日付、たとえば15.04.1896)。指定されたタイムスタンプを正しい日付文字列に変換する方法。

私がやろうとしているので

#include <ctime>
#include <string>
#include <iostream>


int _tmain(int argc, _TCHAR* argv[])
{
    time_t t = std::atol("-2326924800");
    struct tm * ptm;
    ptm = gmtime ( &t );

    std::cout << ptm->tm_year;
    std::cin.get();
    return 0;
}
4

2 に答える 2

2

Windowsを使用しているように見えるので(私はTCHARから推測しています)、おそらくを使用したいと思うでしょうFileTimeToSystemTime()。1601年から何年も使用できます。

例:

#include <windows.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
  SYSTEMTIME sysTime;
  FILETIME fileTime;
  long long seconds;

  sysTime.wYear = 1896;
  sysTime.wMonth = 4;
  sysTime.wDayOfWeek = 0;
  sysTime.wDay = 15;
  sysTime.wHour = 0;
  sysTime.wMinute = 0;
  sysTime.wSecond = 0;
  sysTime.wMilliseconds = 0;

  if (SystemTimeToFileTime(&sysTime, &fileTime))
  {
    seconds = *(long long*)&fileTime;
    seconds /= 10000000; // 100-nanoseconds to seconds since Jan 1st 1601
    seconds -= 11644473600; // 1601 to 1970
    printf("%d.%d.%d is %lld seconds from Jan 1st 1970\n",
           sysTime.wDay,
           sysTime.wMonth,
           sysTime.wYear,
           seconds);
  }
  else
  {
    printf("SystemTimeToFileTime() failed with error 0x%X\n", GetLastError());
  }

  // Now, convert it back...

  seconds += 11644473600; // 1970 to 1601
  seconds *= 10000000; // seconds since Jan 1st 1601 to 100-nanoseconds
  *(long long*)&fileTime = seconds;

  memset(&sysTime, 0, sizeof(sysTime));

  if (FileTimeToSystemTime(&fileTime, &sysTime))
  {
    seconds /= 10000000; // 100-nanoseconds to seconds since Jan 1st 1601
    seconds -= 11644473600; // 1601 to 1970
    printf("%lld seconds from Jan 1st 1970 is %d.%d.%d\n",
           seconds,
           sysTime.wDay,
           sysTime.wMonth,
           sysTime.wYear);
  }
  else
  {
    printf("FileTimeToSystemTime() failed with error 0x%X\n", GetLastError());
  }

  return 0;
}

出力:

15.4.1896 is -2326147200 seconds from Jan 1st 1970
-2326147200 seconds from Jan 1st 1970 is 15.4.1896

大まかな見積もり(1896-1970 + 3.5 / 12)* 365.2425 * 24 * 3600は、-2326010337になります。だから、私たちは良いです。

編集

OSまたはコンパイラ固有の関数を使用せずにDIYソリューションが必要な場合は、この回答の秒​​から日付へのコンバータを使用してください。

このスニペットは、その使用方法を示しています。

  struct tm t;
  SecondsSinceEpochToDateTime(&t, -2326924800LL);
  printf("-2326924800 is %d.%d.%d %d:%d:%d\n",
         t.tm_mday,
         t.tm_mon + 1,
         t.tm_year + 1900,
         t.tm_hour,
         t.tm_min,
         t.tm_sec);

そしてこれはそれの出力です:

-2326924800 is 6.4.1896 0:0:0

ええ、-2326924800はグレゴリオ暦では15.4.1896ではありません。6.4です。

于 2012-06-27T10:52:29.207 に答える
1

boost::posix_timeを使用することをお勧めします。

std::cout << boost::posix_time::to_simple_string(boost::posix_time::from_time_t(0) + boost::posix_time::seconds(-2326924800));

time_t負の値を受け入れるように指定されていないため、不適切です (最終的に time_t typedef とは何ですか? を参照してください) 。

于 2012-06-27T10:24:50.857 に答える