两个日期之间的天数C++; 我看到了C++、java的例子,但是对于C++,我找不出计算两个日期之间有多少天的解决方案。
例如,2012-01-24和2013-01-08之间 谢谢 你可以试试图书馆这是一种方法两个日期之间的天数C++; 我看到了C++、java的例子,但是对于C++,我找不出计算两个日期之间有多少天的解决方案。,c++,date,date-arithmetic,C++,Date,Date Arithmetic,例如,2012-01-24和2013-01-08之间 谢谢 你可以试试图书馆这是一种方法 #include <iostream> #include <ctime> int main() { struct std::tm a = {0,0,0,24,5,104}; /* June 24, 2004 */ struct std::tm b = {0,0,0,5,6,104}; /* July 5, 2004 */ std::time_t x = st
#include <iostream>
#include <ctime>
int main()
{
struct std::tm a = {0,0,0,24,5,104}; /* June 24, 2004 */
struct std::tm b = {0,0,0,5,6,104}; /* July 5, 2004 */
std::time_t x = std::mktime(&a);
std::time_t y = std::mktime(&b);
if ( x != (std::time_t)(-1) && y != (std::time_t)(-1) )
{
double difference = std::difftime(y, x) / (60 * 60 * 24);
std::cout << std::ctime(&x);
std::cout << std::ctime(&y);
std::cout << "difference = " << difference << " days" << std::endl;
}
return 0;
}
将日期转换为整数,表示从一个纪元开始的天数,然后减去。在我选择的这个例子中,算法的解释可以在
int
第一天是0001-01-01*/
if(m<3)
y--,m+=12;
返回365*y+y/4-y/100+y/400+(153*m-457)/5+d-306;
}
国际日=rdn(2013,1,8)-rdn(2012,1,24);
为了避免使用自己的功能,您可以使用Boost提供的日期时间。旧问题的新答案:
使用此选项,您现在可以编写:
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
auto x = 2012_y/1/24;
auto y = 2013_y/1/8;
cout << x << '\n';
cout << y << '\n';
cout << "difference = " << (sys_days{y} - sys_days{x}).count() << " days\n";
}
如果您不想依赖这个库,您可以使用上面的日期库使用的相同日期算法编写自己的。它们可以在本文中找到:。本例中使用的本文算法如下:
// 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;
}
//返回自civil 1970-01-01以来的天数。负值表示
//1970-01-01之前的天。
//前提条件:y-m-d表示民事(公历)日历中的日期
//m在[1,12]中
//d在[1,月的最后一天(y,m)]
//y是“近似”in
//[数值限制::最小值()/366,数值限制::最大值()/366]
//准确的有效范围为:
//[civil_from_days(数值限制::min()),
//civil_from_days(数字限制::max()-719468)]
模板
常量表达式
Int
从civil开始的天数(整数y,无符号m,无符号d)无例外
{
静态断言(标准::数字限制::数字>=18,
“此算法尚未移植到16位无符号整数”);
静态断言(标准::数字限制::数字>=20,
“此算法尚未移植到16位有符号整数”);
y-=m=0?y:y-399)/400;
const unsigned yoe=static_cast(y-era*400);/[0399]
常数无符号doy=(153*(m+(m>2?-3:9))+2)/5+d-1;//[0365]
const unsigned doe=yoe*365+yoe/4-yoe/100+doy;//[0,146096]
返回纪元*146097+静态施法(doe)-719468;
}
有关此算法的工作原理、单元测试及其有效性范围的详细信息,请参阅
该算法对模型进行建模,无限期地向前和向后扩展公历。要对其他日历(如朱利安日历)建模,您将需要其他算法。一旦设置了其他日历,并同步到同一系列历元(这些算法使用1970-01-01格里高利历元,也就是历元),您就可以轻松地计算任意两个日期之间的天数,也可以计算建模的任意两个日历之间的天数
这使您不必为从朱利安到格里高利的转换日期硬编码。您只需知道输入数据所参照的日历
有时,历史文件中可能模棱两可的日期会分别标注为儒略历或公历
如果您还关心日期的时间,那么这将与
库无缝集成,以使用小时
,分钟
,秒
,毫秒
,微秒
和纳秒
,以及系统时钟::now()
获取当前日期和时间
如果您关心时区,则会在顶部另外写一个(单独的)以使用处理时区。如果需要,还提供了计算功能,包括。到目前为止您尝试了什么?您使用什么数据类型来存储此日期?在我看来,它可以像
(date1-date2)一样简单代码>甚至,使用C++11和适当的代码(“2012-01-24”\u日期-“2013-01-08”\u日期)。到\u天()代码>如果您要对历史数据使用此算法,请注意,因为过去是惊人的不连续的。例如,1582/10/5和1582/10/14之间有多少天?答:有一个RF要发布,让我把它的Burdii看到这个(否则我就不知道它),但是很难看到。谢谢你的暗示,我会在下一个副本中考虑这个问题,你也应该强调它是行不通的。如果日期跨越在夏季和冬季之间更改的日期,则可能会得到不一致的结果。(对时间使用12:0:0
,而不是0:0:0
),当然,struct tm
中元素的顺序没有指定;你需要像std::tma;a、 tm_年=104;a、 tm_mon=5;a、 tm_mday=24;a、 tm_小时=12代码>。这种方法不考虑夏时制时间偏移、闰秒或公历中的洞。只要你总是考虑每天的午夜,并将其四舍五入到最接近的天数,前两个陷阱就不会伤害你。只要你不使用跨越一个洞的日期范围(1582年之后的任何时间都是安全的),第三个陷阱也不会让你得逞。(153*m-457)/5+d-306
意味着什么?@immiao,算法将2月移到年底(153*m-457)/5
计算当月的前几天数。一年中的3月1日到12月31日之间有306天。
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
auto x = 2012_y/1/24;
auto y = 2013_y/1/8;
cout << x << '\n';
cout << y << '\n';
cout << "difference = " << (sys_days{y} - sys_days{x}).count() << " days\n";
}
2012-01-24
2013-01-08
difference = 350 days
// 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;
}