web-dev-qa-db-ja.com

エポック時間を「実際の」日付/時間に変換する

私がやりたいことは、エポック時間(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;
}

メンバーsecondsminuteshoursmonthday、およびyearがすべて存在すると想定できます。

forループを使用して元の時間を変更すると少し気分が悪くなり、これに対する「より良い」解決策があるかどうか疑問に思っていました。

23
Austin Hyde

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;
}
18
rxin

標準ライブラリは、これを行うための関数を提供します。 gmtime()またはlocaltime()は、_time_t_(エポックからの秒数、つまり1970年1月1日00:00:00)を_struct tm_に変換します。 strftime()を使用すると、指定した形式に基づいて_struct tm_を文字列(_char*_)に変換できます。

参照してください: http://www.cplusplus.com/reference/clibrary/ctime/

日付/時刻の計算は注意が必要です。本当に正当な理由がない限り、独自のソリューションを使用するよりも、既存のソリューションを使用する方がはるかに優れています。

14
sdtom

簡単な方法(必要な形式とは異なります):

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());

取得元: http://en.cppreference.com/w/cpp/chrono/c/time

3
brkeyal
time_t t = unixTime;
cout << ctime(&t) << endl;
1
user4513421

元の時間タイプがtime_tの場合、移植可能なコードを取得するには、time.hの関数、つまりgmtimeなどを使用する必要があります。 C/C++標準は、time_tの内部形式(または正確な型)を指定していないため、time_t値を直接変換または操作することはできません。

知られているのは、time_tが「算術型」であることだけですが、算術演算の結果は指定されていません。確実に加算/減算することさえできません。実際には、多くのシステムはエポック以降の内部形式が秒のtime_tに整数型を使用していますが、これは標準では強制されていません。

要するに、gmtime(およびtime.h機能全般)を使用します。

0
eidolon