27

私がしたいのは、エポック時間 (1970 年 1 月 1 日午前 0 時からの秒数) を「リアルタイム」時間 (m/d/yh: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メンバー、minuteshoursmonthday、およびyearすべてが存在すると想定できます。

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

4

7 に答える 7

20

daysInMonth 関数ではうるう年に注意してください。

非常に高いパフォーマンスが必要な場合は、ペアを事前計算して月 + 年を 1 ステップで取得してから、日/時間/分/秒を計算できます。

良い解決策は、gmtime ソース コードの 1 つです。

/*
 * 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;
}
于 2009-11-07T06:26:38.597 に答える
17

標準ライブラリには、これを行うための関数が用意されています。gmtime()または(エポックからの秒数、つまり 1970 年 1 月 1 日 00:00:00) を a に変換しlocaltime()ます。を使用して、指定した形式に基づいてa を文字列 ( ) に変換できます。time_tstruct tmstrftime()struct tmchar*

参照: http://www.cplusplus.com/reference/clibrary/ctime/

日付/時刻の計算は複雑になる場合があります。本当に正当な理由がない限り、独自のソリューションを展開するよりも、既存のソリューションを使用する方がはるかに優れています。

于 2009-11-07T06:29:09.307 に答える
1

エポック文字列を UTC に変換するには

string epoch_to_utc(string epoch) {
  long temp = stol(epoch);
  const time_t old = (time_t)temp;
  struct tm *oldt = gmtime(&old);
  return asctime(oldt);
}

そして、それは次のように呼び出すことができます

  string temp = "245446047";
  cout << epoch_to_utc(temp);

出力:

Tue Oct 11 19:27:27 1977
于 2021-01-28T18:36:18.910 に答える
0

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

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

つまり、gmtime (および一般的な time.h 機能) を使用します。

于 2009-11-07T11:52:33.857 に答える