を返します。整数についての抽象、日時への変換Howard Hinnant's free, open-source, header-only libraryはそのようなツールです。
{year, month, day}
date::year_month_day
と呼ばれるクラスで、年と月の演算に適しています。
int
membershipFine(date::year_month_day joinDate, date::year_month_day currentDate);
期日のご説明は、それが一日とは無関係であることを言って表示されます。一つは、ちょうど2つのタイプセーフなパラメータする6種類の危険なパラメータを取ってからmembershipFine
のAPIを変更するためにこれを使用することができます参加日の1ヶ月、参加日の月の初めから1週間少ない1年であることを確認します。これが本当であるならば、これは簡単にこのように計算することができます。
using namespace date;
year_month_day dueDate{
local_days{(joinDate.year()/joinDate.month() + years{1})/1} - weeks{1}};
表現joinDate.year()/joinDate.month()
がjoinDate
から日の-ヶ月を無視し、ちょうど一年と月ですyear_month
オブジェクトを作成します。私は1年をそのyear_month
に追加し、正確に1年後に別のyear_month
という結果になります。
その合計には、/1
が追加されています。これにより、前述のyear_month
の月の初日に対応するyear_month_day
が作成されます。
year_month_day
は、year
とmonth
の指向の計算には適していますが、曜日と週指向の計算ではそれほど大きくありません。そのための最良のデータ構造は、ある時代の{count-of-days}
です。このライブラリはlocal_days
というデータ構造を持っています。だから私はそれに変換し、1週間を引いた後、year_month_day
に戻って変換します。
これのすべて(期日を計算するため)は、上記のコード行で行われます。
currentDate
とdueDate
の関係に基づいて、fine
を計算する必要があります。fine
はcurrentDate < dueDate
場合、$ 0になり、それ以外の場合は全体の数ヶ月の数の関数である(プラス1)currentDate
は(私はあなたの問題文を理解して)dueDate
を超えています:
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;
}
ヶ月の違い、日無視します-of-the-monthは、year_month
オブジェクトに変換して減算することで計算できます。今、currentDate.day() < dueDate.day()
の場合、これは正解です。たとえば、月の相違が1であるのに、currentDate
の月の日がdueDate
の月の日をまだ超えていない場合は、2か月間は請求したくありません。もしそうなら、differenceInMonths
がインクリメントされます。
その後fine
は、単にdifferenceInMonths
あり、そこに任意の<chrono>
ファンがある場合は、differenceInMonths
の種類は、実際に正確である期間とstd::chrono::duration
で一体化し、回15
<aside>
にmonths
から変換平均月。したがって、.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';
}
この出力:
join Date is 2016-02-29
due Date is 2017-01-25
current Date is 2017-01-24
fine is $0
0
join Date is 2016-02-29
due Date is 2017-01-25
current Date is 2017-01-25
fine is $15
15
join Date is 2016-02-29
due Date is 2017-01-25
current Date is 2017-02-24
fine is $15
15
join Date is 2016-02-29
due Date is 2017-01-25
current Date is 2017-02-25
fine is $30
30
を要約すると、このようなライブラリを使用すると、int
の数で考える必要がなくなり、日付とカレンダーの観点から実装する必要があるロジックに集中することができます。結果は、はるかに正しい可能性があるコンパクトで読みやすいコードです。 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";
}
あなたには、いくつかの他の形式、here is the complete list of parsing flags available for useを求めることを好む場合。
そして、OPは現在の日付を取得する方法を尋ねます。複数の答えがあります。あなたはUTCでの現在の日付と内容であれば、それが最も簡単です:
using namespace std::chrono;
using namespace date;
year_month_day today = floor<days>(system_clock::now());
あなたのローカルタイムゾーンの現在の日付をしたい場合は、あなたが"date/tz.h"
(requires some installation)を使用する必要があり、この構文:
year_month_day today{floor<days>(make_zoned(current_zone(),
system_clock::now()).get_local_time())};
あなたが行うことができますあなたの現在のローカルタイムゾーン以外のいくつかの時間帯に現在の日付を希望しない場合:どんなにあなたのp
year_month_day today{floor<days>(make_zoned("America/Los_Angeles",
system_clock::now()).get_local_time())};
一般的なアドバイスが読みやすいようにコードをフォーマットしようとして
std::cout << membershipFine(join, today) << '\n';
:あなたの
join
とtoday
お尻、彼らはこのように使用することができます。また、実際のエラーまたは予期しない出力が何であるかを示します。宿題の一部で、あなたが求めている質問を理解することができます。 – MrJLP