我对这个程序有一个小问题。我正在尝试创建一个计算个人生活天数的c ++程序。它接受三个称为月,日和年的参数。这是该计划背后的全部逻辑:
首先计算今天的日期并保存为三个变量,分别称为日,月和年,并找出年份差异
假设年份差异为10,则乘以365计算9年中的天数。
假设输入月份为5,通过添加相应的天数计算4个月内的天数,并将结果值添加到总天数中。
计算从输入年到当年的闰年数,并将该值添加到总天数中。
函数返回最终输出但是我在某些日期会出现轻微错误。输出并不总是准确的。任何帮助将不胜感激。 下面是整个代码:
#include <iostream>
#include <ctime>
#include <cmath>
#include <vector>
using namespace std;
bool IsLeap(int);
int LeapCount(int);
int current_year;
int calculator(int month, int day, int year);
int main()
{
cout << calculator(9,24,1994);
}
int calculator(int month, int day, int year)
{
int final_result;
int day_difference;
int total_days = 0;
const int days_inayear = 365;
vector <int> m_days = {31,28,31,30,31,30,31,31,30,31,30,31};
time_t theTime = time(NULL);
struct tm *aTime = localtime(&theTime);
int current_day = aTime->tm_mday;
int current_month = aTime->tm_mon + 1;
current_year = aTime->tm_year + 1900;
if(year > current_year){
return 0;
}
else if (year == current_year && month > current_month){
return 0;
}
else if(year == current_year && month == current_month && day > current_day){
return 0;
}
else if(year == current_year &&month == current_month && day <= current_day){
return abs(current_day - day);
}else
{
int year_difference = current_year - year;
int day_difference = abs(current_day - day);
for(int a = month+1; a < m_days.size(); a++){
total_days+= m_days[a];
}
int leap_years = LeapCount(year);
total_days+=(year_difference)*days_inayear;
if(year_difference <= 1 && month < 2){
leap_years -= 2;
}
final_result = total_days+leap_years+day_difference;
if(IsLeap(year) && month > 2){
final_result = final_result;
}
return final_result;
}
}
bool IsLeap(int year)
{
if(year%4 == 0 && year%100!=0){
return true;
}
else if(year%4==0 && year%100==0 && year%400==0){
return true;
}
else{
return false;
}
}
int LeapCount(int year)
{
int difference = current_year - year;
int count = 0;
for(int x = 0; x<=difference; x++){
if(IsLeap(year+x)){
count++;
}
}
return count;
}
答案 0 :(得分:0)
使用日期计算并不是一项特别简单明了的任务,只是简单地使用经过验证的算法而不是尝试调试破坏的算法更容易。
来自Howard Hinnant的论文chrono
-Compatible Low-Level Date Algorithms,这是一个算法,计算自1970-01-01以来的天数:
#include <limits>
#include <iostream>
// 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;
}
这个实现碰巧使用C ++ 14的功能,但是将其转换为C ++ 11甚至是C ++ 98并不困难。
这是一个非常聪明的算法。霍华德的论文详细解释了这些细节。
要计算两个日期之间的天数,请使用此算法计算两个不同日期的纪元的天数,然后减去这些值以获得它们之间的天数
int main() {
int serial_birth_date = days_from_civil(1994, 9, 24);
int serial_current_date = days_from_civil(2013, 11, 24);
std::cout << "Days lived: " << serial_current_date - serial_birth_date << '\n';
}
如果您真的想调试自己的算法,可以使用霍华德发布的算法作为基线。将程序的各个组件的结果与使用这些算法计算的结果进行比较,以将问题缩小到单个组件。比较大量测试用例的结果,也许你会在错误中看到一个模式。