【问题标题】:Converting epoch time to "real" date/time将纪元时间转换为“真实”日期/时间
【发布时间】:2010-12-14 02:42:26
【问题描述】:

我想要做的是将纪元时间(自 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;
}

您可以假设成员secondsminuteshoursmonthdayyear 都存在。

使用for 循环修改原来的时间感觉有点不对劲,我想知道是否有“更好”的解决方案。

【问题讨论】:

  • 仅仅调用 time.h 公开的这个功能有什么问题,例如gmtime 如果您要的是 GMT 而不是某个特定的时区?
  • 没什么问题,我什至不知道它存在。谢谢!但是,我仍然很想知道我的实现如何才能做得更好。
  • @Austin,“谢谢”和不赞成不符合正常的 SO 礼仪!-)
  • (让我赶紧指出这不是自私自利的,因为无论如何我今天已经筋疲力尽了:这是关于 SO 基本礼仪的顺利和正常应用——你投票回答你找到有用的!!!)。
  • 好的,所以我知道您正在寻找程序解决方案...但如果您还没有看到它,请查看epochconverter.com。这是检查您的工作的非常有用的方法:)

标签: c++ algorithm datetime epoch


【解决方案1】:

在 daysInMonth 函数中注意闰年。

如果您想要非常高的性能,您可以预先计算该对以一步得到月+年,然后计算日/小时/分钟/秒。

一个好的解决方案是gmtime source code

/*
 * 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 源代码的链接已损坏。
【解决方案2】:

标准库提供了执行此操作的函数。 gmtime()localtime() 会将 time_t(自纪元以来的秒数,即 - 1970 年 1 月 1 日 00:00:00)转换为 struct tm。然后,strftime() 可用于根据您指定的格式将 struct tm 转换为字符串 (char*)。

见:http://www.cplusplus.com/reference/clibrary/ctime/

日期/时间计算可能会变得很棘手。除非你有充分的理由,否则你最好使用现有的解决方案,而不是尝试推出自己的解决方案。

【讨论】:

  • 这开始是前一段时间的家庭作业,但现在我有兴趣让它变得更好。通常情况下,我会选择库解决方案,但是 1)我不知道内置的时间函数和 2)我想完善我的实现。
【解决方案3】:

一种简单的方法(尽管与您想要的格式不同):

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

【讨论】:

  • time.cpp:在函数'int main()'中:time.cpp:6:36:错误:'nullptr'未在此范围内声明 std::time_t 结果 = std::time (nullptr);
【解决方案4】:
time_t t = unixTime;
cout << ctime(&t) << endl;

【讨论】:

  • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
【解决方案5】:

此代码可能会对您有所帮助。

#include <iostream>
#include <ctime>

using namespace std;

int main() {
   // current date/time based on current system
   time_t now = time(0);
   
   // convert now to string form
   char* dt = ctime(&now);

   cout << "The local date and time is: " << dt << endl;

   // convert now to tm struct for UTC
   tm *gmtm = gmtime(&now);
   dt = asctime(gmtm);
   cout << "The UTC date and time is:"<< dt << endl;
}

【讨论】:

    【解决方案6】:

    将纪元字符串转换为 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
    

    【讨论】:

    • 很好,如何打印成1977-10-11 19:27:27格式?
    【解决方案7】:

    如果您的原始时间类型是 time_t,则必须使用 time.h 中的函数,即 gmtime 等来获取可移植代码。 C/C++ 标准没有指定 time_t 的内部格式(甚至是确切的类型),因此您不能直接转换或操作 time_t 值。

    所有已知的是 time_t 是“算术类型”,但没有指定算术运算的结果 - 你甚至不能可靠地加/减。在实践中,许多系统对 time_t 使用整数类型,内部格式为自纪元以来的秒数,但这不是标准强制执行的。

    简而言之,使用 gmtime(以及一般的 time.h 功能)。

    【讨论】:

      猜你喜欢
      • 2012-09-06
      • 2018-04-24
      • 2011-12-06
      • 2021-03-25
      • 2012-11-08
      • 2019-01-15
      • 2019-11-14
      • 2013-01-08
      • 2018-11-09
      相关资源
      最近更新 更多