C++ 将1970年以来的秒数转换为日期,反之亦然
从1970年1月1日00:00开始,我有几秒钟的时间是以纳秒为单位的int64,我正在尝试将其转换为月/日/年/周/日C++ 将1970年以来的秒数转换为日期,反之亦然,c++,date,math,C++,Date,Math,从1970年1月1日00:00开始,我有几秒钟的时间是以纳秒为单位的int64,我正在尝试将其转换为月/日/年/周/日 迭代的方法很容易做到,我已经做到了,但是我想用公式化的方法来做。我在寻找实际的数学。有很多函数可以实现这一点,请参见,即 将其作为第一个参数传递秒数。第二个参数对于本地时间应该为true,对于GMT应该为false。第三个参数是指向保存响应的结构的指针 返回结构包括(从手册页): tm_sec:分钟后的秒数,通常在0到0之间 59,但可以高达60以允许闰秒 tm_min:小时后
迭代的方法很容易做到,我已经做到了,但是我想用公式化的方法来做。我在寻找实际的数学。有很多函数可以实现这一点,请参见,即 将其作为第一个参数传递秒数。第二个参数对于本地时间应该为true,对于GMT应该为false。第三个参数是指向保存响应的结构的指针 返回结构包括(从手册页): tm_sec:分钟后的秒数,通常在0到0之间 59,但可以高达60以允许闰秒 tm_min:小时后的分钟数,范围为0到59 tm_hour:午夜后的小时数,范围为0到23 TMmday:一个月中的一天,范围为1到31 tm_mon:自1月以来的月数,范围为0到11 tm_年:自1900年以来的年数 tm_wday:自星期日起的天数,范围为0到6 tm_yday:自1月1日起的天数,范围为0到365 tm_isdst:指示夏令时是否生效的标志 在描述的时间。如果采用夏令时,则该值为正值 时间是有效的,如果不是,则为零,如果 目前没有这方面的资料
取决于您想要的时间,或者只需阅读首先,不要将秒存储为浮点。如果需要微秒/纳秒,请分别存储。你需要整数来做这些计算 这取决于您所在的时区(DST规则、闰年、闰秒),但我想说的是,首先得到天数除以86400的整数。然后通过模除以86400,找出剩下的是什么。现在,您可以通过第一个整数将天数除以365,然后从剩余天数中减去闰日数(通过天数除以365的模计算)来计算已经过去了多少年。您还需要从剩余秒数(已计算)中减去闰秒数。如果减法使这些数字降到零以下,那么从下一个最大的面额中减法。然后,您可以使用日历的显式逻辑计算月份的日期。如果您在DST着陆,请确保添加一小时(或DST偏移量为多少)
就我个人而言,我只想使用,因为它可以完成所有这些和更多(可能比您或我在最初几次迭代中犯的错误要少),但我想我会尝试一下您的问题…单一Unix规范给出了以下公式: 一个近似已过秒数的值 从古至今。协调世界时名称(以术语指定) 秒(tm_秒)、分钟(tm_分钟)、小时(tm_小时)、天(自 一年中的1月1日(tm_yday),日历年减去1900 (tm_year))与自 纪元,根据下面的表达式 如果年份=1970且值为非负值,则 值与根据 C语言表达式,其中tm_sec、tm_min、tm_hour、tm_yday和 tm_年均为整数类型:
tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +
(tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -
((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400
一天中的实际时间与当前值之间的关系
自未指定纪元起的秒数
如何更改自历元以来秒的值
将所需关系与当前实际时间对齐
实现定义。从新纪元开始以秒为单位表示,
每一天都应精确计算86400秒
注:
该表达式的最后三个术语为闰年之后的每一年加上一天,从第一个闰年开始
纪元从1973年开始,第一个任期每四年增加一天
第二,从2001年开始,每100年减去一天
从2001年开始,每400年增加一天。这个
公式中的除法为整数除法;也就是说,剩余的
被丢弃,只留下整数商
要使用这个公式,您需要将月和月的日转换为tmyday,这也应该考虑闰年。公式中的其余部分微不足道
试着从中找出如何从秒数返回日期和时间
编辑:
我在中实现了一个整数算术转换器
.此代码有效
用法:
uint32获取安全历元(1970年,自历元起的月、日、年、小时、分钟、秒)
例如:
timestamp=getSecsSinceEpoch(1970,6,12,(2014-1970),15,29,0)
退货:1402586940
您可以在www.epochconverter.com上进行验证
写这篇文章花了大约20分钟,大部分时间都花在和一个朋友争论我是否应该包括闰秒、纳秒等等
玩得开心
布莱恩·威尔卡特博士
#define DAYSPERWEEK (7)
#define DAYSPERNORMYEAR (365U)
#define DAYSPERLEAPYEAR (366U)
#define SECSPERDAY (86400UL) /* == ( 24 * 60 * 60) */
#define SECSPERHOUR (3600UL) /* == ( 60 * 60) */
#define SECSPERMIN (60UL) /* == ( 60) */
#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
const int _ytab[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
/****************************************************
* Class:Function : getSecsSomceEpoch
* Input : uint16_t epoch date (ie, 1970)
* Input : uint8 ptr to returned month
* Input : uint8 ptr to returned day
* Input : uint8 ptr to returned years since Epoch
* Input : uint8 ptr to returned hour
* Input : uint8 ptr to returned minute
* Input : uint8 ptr to returned seconds
* Output : uint32_t Seconds between Epoch year and timestamp
* Behavior :
*
* Converts MM/DD/YY HH:MM:SS to actual seconds since epoch.
* Epoch year is assumed at Jan 1, 00:00:01am.
****************************************************/
uint32_t getSecsSinceEpoch(uint16_t epoch, uint8_t month, uint8_t day, uint8_t years, uint8_t hour, uint8_t minute, uint8_t second)
{
unsigned long secs = 0;
int countleap = 0;
int i;
int dayspermonth;
secs = years * (SECSPERDAY * 365);
for (i = 0; i < (years - 1); i++)
{
if (LEAPYEAR((epoch + i)))
countleap++;
}
secs += (countleap * SECSPERDAY);
secs += second;
secs += (hour * SECSPERHOUR);
secs += (minute * SECSPERMIN);
secs += ((day - 1) * SECSPERDAY);
if (month > 1)
{
dayspermonth = 0;
if (LEAPYEAR((epoch + years))) // Only counts when we're on leap day or past it
{
if (month > 2)
{
dayspermonth = 1;
} else if (month == 2 && day >= 29) {
dayspermonth = 1;
}
}
for (i = 0; i < month - 1; i++)
{
secs += (_ytab[dayspermonth][i] * SECSPERDAY);
}
}
return secs;
}
#定义DAYSPERWEEK(7)
#定义DAYSPERNORMYEAR(365U)
#定义DAYSPERLEAPYEAR(366U)
#定义SECSPERDAY(86400UL)/*==(24*60*60)*/
#定义SECSPERHOUR(3600UL)/*==(60*60)*/
#定义SECSPERMIN(60UL)/*=(60)*/
#定义闰年(年)(!((年)%4)&((年)%100)| |!((年)%400)))
国际常数[2][12]={
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
/****************************************************
*类:函数:getSecsSomceEpoch
*输入:uint16_t纪元日期(即1970年)
*输入:返回月份的uint8 ptr
*输入:返回日期的uint8 ptr
*输入:用户界面
#define DAYSPERWEEK (7)
#define DAYSPERNORMYEAR (365U)
#define DAYSPERLEAPYEAR (366U)
#define SECSPERDAY (86400UL) /* == ( 24 * 60 * 60) */
#define SECSPERHOUR (3600UL) /* == ( 60 * 60) */
#define SECSPERMIN (60UL) /* == ( 60) */
#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
const int _ytab[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
/****************************************************
* Class:Function : getSecsSomceEpoch
* Input : uint16_t epoch date (ie, 1970)
* Input : uint8 ptr to returned month
* Input : uint8 ptr to returned day
* Input : uint8 ptr to returned years since Epoch
* Input : uint8 ptr to returned hour
* Input : uint8 ptr to returned minute
* Input : uint8 ptr to returned seconds
* Output : uint32_t Seconds between Epoch year and timestamp
* Behavior :
*
* Converts MM/DD/YY HH:MM:SS to actual seconds since epoch.
* Epoch year is assumed at Jan 1, 00:00:01am.
****************************************************/
uint32_t getSecsSinceEpoch(uint16_t epoch, uint8_t month, uint8_t day, uint8_t years, uint8_t hour, uint8_t minute, uint8_t second)
{
unsigned long secs = 0;
int countleap = 0;
int i;
int dayspermonth;
secs = years * (SECSPERDAY * 365);
for (i = 0; i < (years - 1); i++)
{
if (LEAPYEAR((epoch + i)))
countleap++;
}
secs += (countleap * SECSPERDAY);
secs += second;
secs += (hour * SECSPERHOUR);
secs += (minute * SECSPERMIN);
secs += ((day - 1) * SECSPERDAY);
if (month > 1)
{
dayspermonth = 0;
if (LEAPYEAR((epoch + years))) // Only counts when we're on leap day or past it
{
if (month > 2)
{
dayspermonth = 1;
} else if (month == 2 && day >= 29) {
dayspermonth = 1;
}
}
for (i = 0; i < month - 1; i++)
{
secs += (_ytab[dayspermonth][i] * SECSPERDAY);
}
}
return secs;
}
// Returns number of days since civil 1970-01-01. Negative values indicate
// days prior to 1970-01-01.
// Preconditions: y-m-d represents a date in the civil (Gregorian) calendar
// m is in [1, 12]
// d is in [1, last_day_of_month(y, m)]
// y is "approximately" in
// [numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
// Exact range of validity is:
// [civil_from_days(numeric_limits<Int>::min()),
// civil_from_days(numeric_limits<Int>::max()-719468)]
template <class Int>
constexpr
Int
days_from_civil(Int y, unsigned m, unsigned d) noexcept
{
static_assert(std::numeric_limits<unsigned>::digits >= 18,
"This algorithm has not been ported to a 16 bit unsigned integer");
static_assert(std::numeric_limits<Int>::digits >= 20,
"This algorithm has not been ported to a 16 bit signed integer");
y -= m <= 2;
const Int era = (y >= 0 ? y : y-399) / 400;
const unsigned yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
const unsigned doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1; // [0, 365]
const unsigned doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096]
return era * 146097 + static_cast<Int>(doe) - 719468;
}
// Returns year/month/day triple in civil calendar
// Preconditions: z is number of days since 1970-01-01 and is in the range:
// [numeric_limits<Int>::min(), numeric_limits<Int>::max()-719468].
template <class Int>
constexpr
std::tuple<Int, unsigned, unsigned>
civil_from_days(Int z) noexcept
{
static_assert(std::numeric_limits<unsigned>::digits >= 18,
"This algorithm has not been ported to a 16 bit unsigned integer");
static_assert(std::numeric_limits<Int>::digits >= 20,
"This algorithm has not been ported to a 16 bit signed integer");
z += 719468;
const Int era = (z >= 0 ? z : z - 146096) / 146097;
const unsigned doe = static_cast<unsigned>(z - era * 146097); // [0, 146096]
const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399]
const Int y = static_cast<Int>(yoe) + era * 400;
const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365]
const unsigned mp = (5*doy + 2)/153; // [0, 11]
const unsigned d = doy - (153*mp+2)/5 + 1; // [1, 31]
const unsigned m = mp + (mp < 10 ? 3 : -9); // [1, 12]
return std::tuple<Int, unsigned, unsigned>(y + (m <= 2), m, d);
}
// Returns day of week in civil calendar [0, 6] -> [Sun, Sat]
// Preconditions: z is number of days since 1970-01-01 and is in the range:
// [numeric_limits<Int>::min(), numeric_limits<Int>::max()-4].
template <class Int>
constexpr
unsigned
weekday_from_days(Int z) noexcept
{
return static_cast<unsigned>(z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6);
}
#include <iostream>
int
main()
{
int64_t z = days_from_civil(2015LL, 8, 22);
int64_t ns = z*86400*1000000000;
std::cout << ns << '\n';
const char* weekdays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
unsigned wd = weekday_from_days(z);
int64_t y;
unsigned m, d;
std::tie(y, m, d) = civil_from_days(ns/86400/1000000000);
std::cout << y << '-' << m << '-' << d << ' ' << weekdays[wd] << '\n';
}
1440201600000000000
2015-8-22 Sat
#include "date/tz.h"
#include <iostream>
int
main()
{
using namespace date;
auto now = clock_cast<utc_clock>(sys_days{2016_y/September/26});
auto then = clock_cast<utc_clock>(sys_days{1970_y/January/1});
std::cout << now - then << '\n';
}
1474848026s
#include "date/date.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono_literals;
auto now = sys_days{2016_y/September/26} + 0s;
auto then = sys_days{1970_y/January/1};
std::cout << now - then << '\n';
}
1474848000s
for (i = 0; i < (years - 1); i++)
{
if (LEAPYEAR((epoch + i)))
countleap++;
}
for (i = 0; i < years; i++)
{
if (LEAPYEAR((epoch + i)))
countleap++;
}
static long UnixTime ( int sec, int min, int hour, int day, int month, int year )
{
// Cumulative days for each previous month of the year
int[] mdays = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
// Year is to be relative to the epoch start
year -= 1970;
// Compensation of the non-leap years
int minusYear = 0;
// Detect potential lead day (February 29th) in this year?
if ( month >= 3 )
{
// Then add this year into "sum of leap days" computation
year++;
// Compute one year less in the non-leap years sum
minusYear = 1;
}
return
// + Seconds from computed minutes
60 * (
// + Minutes from computed hours
60 * (
// + Hours from computed days
24 * (
// + Day (zero index)
day - 1
// + days in previous months (leap day not included)
+ mdays[month - 1]
// + days for each year divisible by 4 (starting from 1973)
+ ( ( year + 1 ) / 4 )
// - days for each year divisible by 100 (starting from 2001)
- ( ( year + 69 ) / 100 )
// + days for each year divisible by 400 (starting from 2001)
+ ( ( year + 369 ) / 100 / 4 )
// + days for each year (as all are non-leap years) from 1970 (minus this year if potential leap day taken into account)
+ ( 5 * 73 /*=365*/ ) * ( year - minusYear )
// + Hours
) + hour
// + Minutes
) + min
// + Seconds
) + sec;
}
uns32 unixTime;
...
// Test data returning 0xFfFfFfFf UnixTime
uns8 year = 2106 - 1970;
uns8 month = 2;
uns8 day = 7;
uns8 hour = 6;
uns8 min = 28;
uns8 sec = 15;
// See original C# code below
//### Compute days
// ( 5 * 73 /*=365*/ ) * year
unixTime = year;
mulUnixTime( 5 );
mulUnixTime( 73 );
// if ( month >= 3 ) year++;
if ( month > 3 )
year++;
// if ( year > 130 ) => minus 1 total days ( year-=4 makes a result of the next division by 4 less by 1)
if ( year > 130 )
year -= 4;
// + ( ( year + 1 ) / 4 )
addUnixTime( ( year + 1 ) / 4 );
// + mdays[month - 1]
addUnixTime( daysInMonths( month ) );
// + day - 1
addUnixTime( day - 1 );
//### Compute hours
// Hours from computed days
mulUnixTime( 24 );
// + Hours
addUnixTime( hour );
//### Compute minutes
// Minutes from computed hours
mulUnixTime( 60 );
// + Minutes
addUnixTime( min );
//### Compute seconds
// Seconds from computed minutes
mulUnixTime( 60 );
// + Seconds
addUnixTime( sec );
...
void mulUnixTime( uns8 mul )
{
unixTime *= mul;
}
void addUnixTime( uns8 add )
{
unixTime += add;
}
uns8 daysInMonths( uns8 month @ W )
{
skip( month );
#pragma computedGoto 1
return 0xFF;// Dummy value for month 0
return 0; // January
return 31; // February
return 59; // ...
return 90;
return 120;
return 151;
return 181;
return 212;
return 243;
return 273;
return 304; // ...
return 334; // December
#pragma computedGoto 0
}
/*
static long UnixTime ( int sec, int min, int hour, int day, int month, int year )
{
// Cumulative days for each previous month of the year
int[] mdays = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
// Year is to be relative to the epoch start
year -= 1970;
// Compensation of the non-leap years
int minusYear = 0;
// Detect potential lead day (February 29th) in this year?
if ( month >= 3 )
{
// Then add this year into "sum of leap days" computation
year++;
// Compute one year less in the non-leap years sum
minusYear = 1;
}
return
// + Seconds from computed minutes
60 * (
// + Minutes from computed hours
60 * (
// + Hours from computed days
24L * (
// + Day (zero index)
day - 1
// + days in previous months (leap day not included)
+ mdays[month - 1]
// + days for each year divisible by 4 (starting from 1973)
+ ( ( year + 1 ) / 4 )
// - days after year 2000
- ( ( year > 130 ) ? 1 : 0 )
// + days for each year (as all are non-leap years) from 1970 (minus this year if potential leap day taken into account)
+ ( 5 * 73 ) * ( year - minusYear )
// + Hours
) + hour
// + Minutes
) + min
// + Seconds
) + sec;
}
*/