私がやりたいことは、エポック時間(1970年1月1日の真夜中からの秒数)を「実際の」時間(m/d/y h:m:s)に変換することです。
これまでのところ、私には次のアルゴリズムがあります。
void DateTime::splitTicks(time_t time) {
seconds = time % 60;
time /= 60;
minutes = time % 60;
time /= 60;
hours = time % 24;
time /= 24;
year = DateTime::reduceDaysToYear(time);
month = DateTime::reduceDaysToMonths(time,year);
day = int(time);
}
int DateTime::reduceDaysToYear(time_t &days) {
int year;
for (year=1970;days>daysInYear(year);year++) {
days -= daysInYear(year);
}
return year;
}
int DateTime::reduceDaysToMonths(time_t &days,int year) {
int month;
for (month=0;days>daysInMonth(month,year);month++)
days -= daysInMonth(month,year);
return month;
}
メンバーseconds
、minutes
、hours
、month
、day
、およびyear
がすべて存在すると想定できます。
for
ループを使用して元の時間を変更すると少し気分が悪くなり、これに対する「より良い」解決策があるかどうか疑問に思っていました。
DaysInMonth関数のうるう年に注意してください。
非常に高いパフォーマンスが必要な場合は、ペアを事前計算して1か月で月と年を取得し、日/時間/分/秒を計算できます。
良い解決策は gmtimeソースコード の解決策です:
/*
* gmtime - convert the calendar time into broken down time
*/
/* $Header: gmtime.c,v 1.4 91/04/22 13:20:27 ceriel Exp $ */
#include <time.h>
#include <limits.h>
#include "loc_time.h"
struct tm *
gmtime(register const time_t *timer)
{
static struct tm br_time;
register struct tm *timep = &br_time;
time_t time = *timer;
register unsigned long dayclock, dayno;
int year = Epoch_YR;
dayclock = (unsigned long)time % SECS_DAY;
dayno = (unsigned long)time / SECS_DAY;
timep->tm_sec = dayclock % 60;
timep->tm_min = (dayclock % 3600) / 60;
timep->tm_hour = dayclock / 3600;
timep->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */
while (dayno >= YEARSIZE(year)) {
dayno -= YEARSIZE(year);
year++;
}
timep->tm_year = year - YEAR0;
timep->tm_yday = dayno;
timep->tm_mon = 0;
while (dayno >= _ytab[LEAPYEAR(year)][timep->tm_mon]) {
dayno -= _ytab[LEAPYEAR(year)][timep->tm_mon];
timep->tm_mon++;
}
timep->tm_mday = dayno + 1;
timep->tm_isdst = 0;
return timep;
}
標準ライブラリは、これを行うための関数を提供します。 gmtime()
またはlocaltime()
は、_time_t
_(エポックからの秒数、つまり1970年1月1日00:00:00)を_struct tm
_に変換します。 strftime()
を使用すると、指定した形式に基づいて_struct tm
_を文字列(_char*
_)に変換できます。
参照してください: http://www.cplusplus.com/reference/clibrary/ctime/
日付/時刻の計算は注意が必要です。本当に正当な理由がない限り、独自のソリューションを使用するよりも、既存のソリューションを使用する方がはるかに優れています。
簡単な方法(必要な形式とは異なります):
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
出力:2011年9月21日水曜日10:27:52
返された結果は自動的に "\ n"で連結されることに注意してください。次のようにして削除できます:
std::string::size_type i = res.find("\n");
if (i != std::string::npos)
res.erase(i, res.length());
time_t t = unixTime;
cout << ctime(&t) << endl;
元の時間タイプがtime_tの場合、移植可能なコードを取得するには、time.hの関数、つまりgmtimeなどを使用する必要があります。 C/C++標準は、time_tの内部形式(または正確な型)を指定していないため、time_t値を直接変換または操作することはできません。
知られているのは、time_tが「算術型」であることだけですが、算術演算の結果は指定されていません。確実に加算/減算することさえできません。実際には、多くのシステムはエポック以降の内部形式が秒のtime_tに整数型を使用していますが、これは標準では強制されていません。
要するに、gmtime(およびtime.h機能全般)を使用します。