我想要做的是将纪元时间(自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
循环来修改原始时间感觉有点偏离,我想知道是否有一个“更好”的解决方案。
答案 0 :(得分:18)
在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;
}
答案 1 :(得分:14)
标准库提供了执行此操作的功能。 gmtime()
或localtime()
会将time_t
(自纪元以来的秒数,即1970年1月1日00:00:00)转换为struct tm
。然后,可以使用strftime()
根据您指定的格式将struct tm
转换为字符串(char*
)。
请参阅:http://www.cplusplus.com/reference/clibrary/ctime/
日期/时间计算可能会变得棘手。除非你有充分的理由,否则你最好不要使用现有的解决方案而不是尝试自己的解决方案。
答案 2 :(得分:3)
一种简单的方法(虽然与您想要的格式不同):
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
输出: 2011年9月21日星期三10:27:52
请注意,返回的结果将自动与&#34; \ n&#34; ...连接。您可以使用以下命令将其删除:
std::string::size_type i = res.find("\n");
if (i != std::string::npos)
res.erase(i, res.length());
答案 3 :(得分:1)
time_t t = unixTime;
cout << ctime(&t) << endl;
答案 4 :(得分: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
答案 5 :(得分:0)
如果您的原始时间类型是time_t,则必须使用time.h中的函数,即gmtime等来获取可移植代码。 C / C ++标准没有为time_t指定内部格式(甚至是精确类型),因此您无法直接转换或操作time_t值。
所有已知的是time_t是“算术类型”,但是没有指定算术运算的结果 - 你甚至无法可靠地加/减。在实践中,许多系统对time_t使用整数类型,内部格式为自纪元以来的秒数,但标准并未强制执行。
简而言之,请使用gmtime(和一般的time.h功能)。
答案 6 :(得分:0)
此代码可能会对您有所帮助。
#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;
}