C++ 在C+中同时使用月份和日期+;
我试图制作一个计算游泳池会员费的程序。用户将输入一个日期(会员最后一次更新会员资格的时间),程序将使用当前日期计算其会员资格是否过期 会员资格将在一年后加入的月份开始前一周(或另一个任意时间段)过期。例如,如果我在2016年2月加入,我必须在2017年1月24日或之前付款,以确保会员资格过期。一到1月25日,应收取一个月的费用(15美元),一到2月25日,应收取两个月的费用等 然而,我不知道如何收费后的几个月,第一次。例如,2月3日付款应导致逾期一个月,但2月26日付款应为两个月,但我不知道如何做到这一点 我如何修复我的函数,因为它似乎不工作? 例如,我已于2016年11月15日入会,由于会员资格于2017年10月24日到期,因此应返回15,但返回0C++ 在C+中同时使用月份和日期+;,c++,date,C++,Date,我试图制作一个计算游泳池会员费的程序。用户将输入一个日期(会员最后一次更新会员资格的时间),程序将使用当前日期计算其会员资格是否过期 会员资格将在一年后加入的月份开始前一周(或另一个任意时间段)过期。例如,如果我在2016年2月加入,我必须在2017年1月24日或之前付款,以确保会员资格过期。一到1月25日,应收取一个月的费用(15美元),一到2月25日,应收取两个月的费用等 然而,我不知道如何收费后的几个月,第一次。例如,2月3日付款应导致逾期一个月,但2月26日付款应为两个月,但我不知道如何
int membershipFine(int joinDay, int joinMonth, int joinYear, int currentDay, int currentMonth, int currentYear)
{
int dueDay[12] = {25, 22, 25, 24, 25, 24, 25, 25, 24, 25, 24, 25}; // the week before the end of each month in days
int correspondingMonth = joinMonth - 2; // finds the element position that corresponds
if (correspondingMonth == -1) // if they joined in january, the array will go to december
{
correspondingMonth = 11;
}
int differenceInMonths = currentMonth - joinMonth + 12 * (currentYear - joinYear);
if (differenceInMonths < 11)
{
return 0;
}
else if ((differenceInMonths == 11) && (joinDay < dueDay[correspondingMonth]))
{
return 0;
}
else if (differenceInMonths == 11)
{
return 15;
}
if (differenceInMonths > 11 && joinDay < dueDay[correspondingMonth]) // not sure about this if and else statement
{
return (differenceInMonths - 11) * 15;
}
else return (differenceInMonths - 10) * 15;
}
int会员资格罚款(int joinDay、int joinMonth、int joinYear、int currentDay、int currentMonth、int currentYear)
{
int dueDay[12]={25,22,25,24,25,25,24,24,25,25,24,25};//每个月结束前的一周,以天为单位
int correspondingmount=joinMonth-2;//查找对应的元素位置
if(correspondingmount==-1)//如果他们在一月加入,数组将转到十二月
{
相应月份=11;
}
int DifferenceInMonth=currentMonth-joinMonth+12*(currentYear-joinYear);
if(差分数<11)
{
返回0;
}
否则如果((差分月数==11)和((联合日<联合日[对应月])
{
返回0;
}
else if(differenceimonths==11)
{
返回15;
}
if(differenceimonths>11&&joinDay 处理日期和时间的最佳方法是使用一个库,将整数的抽象级别提高到日期和时间。是这样一种工具
它有一个名为date::year\u month\u day
的{year,month,day}
类,用于年和月算术。您可以使用它将membershipFine
的API从接受6个类型不安全参数更改为仅接受两个类型安全参数:
int
membershipFine(date::year_month_day joinDate, date::year_month_day currentDate);
您对到期日的描述似乎表明,到期日与加入日期当月的日期无关,并且到期日为1年,从加入日期当月的第一天算起不到1周。如果这是真的,可以很容易地这样计算:
using namespace date;
year_month_day dueDate{
local_days{(joinDate.year()/joinDate.month() + years{1})/1} - weeks{1}};
std::cout << membershipFine(join, today) << '\n';
表达式joinDate.year()/joinDate.month()
创建一个year\u month
对象,该对象仅为一年和一个月,忽略了joinDate
中的月份。我在该年/月
的基础上加上1年,这会导致另一个年/月
,正好是1年后
在这个总数中,附加了/1
。这将创建一个与上述年月
月份的第一天相对应的年月
现在,尽管year\u month\u day
对于面向year
和month
的算法来说是很好的,但是对于面向日和周的算法来说却不是很好。最好的数据结构是某个时代的{countofdays}
。这个库有一个名为local\u days
的数据结构。所以我转换成,减去1周,然后转换回年\月\日
所有这些(计算到期日)都发生在上面的代码行中
现在我需要根据currentDate
和dueDate
之间的关系来计算fine
。如果currentDate
,则罚款为0美元,否则为整月数的函数(加1)currentDate
超过dueDate
(我理解您的问题陈述):
可以通过转换为year\u month
对象并进行减法来计算月差(忽略月的哪一天)。现在如果currentDate.day()
,这就是正确答案。例如,如果月差为1,但currentDate
中的月日尚未超过dueDate
中的月日,则我们不想收取第二个月的费用,否则我们会收取。如果我们这样做,differenceimonths
将递增
然后,fine
就是differenceinmonts
,从months
转换为整数,乘以15
如果有任何
风扇,则差异月数的类型实际上是一个std::chrono::duration
,其周期正好是平均月。因此,.count()
成员函数可以访问基础的整数值
我在上面的代码中添加了一些print语句,下面我用几个示例展示了整个过程以及一个驱动程序:
#include "date/date.h"
#include <iostream>
int
membershipFine(date::year_month_day joinDate, date::year_month_day currentDate)
{
using namespace date;
year_month_day dueDate{
local_days{(joinDate.year()/joinDate.month() + years{1})/1} - weeks{1}};
int fine = 0;
if (currentDate >= dueDate)
{
auto differenceInMonths = currentDate.year()/currentDate.month() -
dueDate.year()/dueDate.month();
if (currentDate.day() >= dueDate.day())
++differenceInMonths;
fine = differenceInMonths.count() * 15;
}
std::cout << "join Date is " << joinDate << '\n';
std::cout << "due Date is " << dueDate << '\n';
std::cout << "current Date is " << currentDate << '\n';
std::cout << "fine is $" << fine << '\n';
return fine;
}
int
main()
{
using namespace date::literals;
std::cout << membershipFine(feb/29/2016, jan/24/2017) << '\n';
std::cout << membershipFine(feb/29/2016, jan/25/2017) << '\n';
std::cout << membershipFine(feb/29/2016, feb/24/2017) << '\n';
std::cout << membershipFine(feb/29/2016, feb/25/2017) << '\n';
}
总之,使用这样的库可以让您不必考虑int
s,因此您可以专注于必须实现的日期和日历逻辑。结果是代码紧凑易读,更有可能是正确的
更新
在下面的评论中,OP询问如何从cin
解析日期以及如何获取当前日期。有几种选择
以下是我建议的约会方式:
date::year_month_day join;
while (true)
{
std::cout << "Enter join date as yyyy-mm-dd: ";
std::cin >> date::parse("%F", join);
if (!std::cin.fail())
break;
std::cin.clear();
std::string garbage;
std::getline(std::cin, garbage);
std::cout << "Please try again.\n";
}
如果希望当前日期位于当前本地时间z以外的某个时区
date::year_month_day join;
while (true)
{
std::cout << "Enter join date as yyyy-mm-dd: ";
std::cin >> date::parse("%F", join);
if (!std::cin.fail())
break;
std::cin.clear();
std::string garbage;
std::getline(std::cin, garbage);
std::cout << "Please try again.\n";
}
using namespace std::chrono;
using namespace date;
year_month_day today = floor<days>(system_clock::now());
year_month_day today{floor<days>(make_zoned(current_zone(),
system_clock::now()).get_local_time())};
year_month_day today{floor<days>(make_zoned("America/Los_Angeles",
system_clock::now()).get_local_time())};
std::cout << membershipFine(join, today) << '\n';