日時計算プログラム③
閏年を考慮した日時計算プログラムを何度かに分けて載せる予定です。
(中身は、むかしANCI-Cで書いたコードをC++クラスで囲っただけです)
応用部
//—————————————————————————–
// 1.関数名 : CalPeriodMMDD
// 2.機能 : 経過月日取得
// 3.引数 : lFromYmd 開始年月日
// : lToYmd 終了年月日
// : *piPeriodMm 経過月数
// : *piPeriodDd 経過日数
// 4.戻り値 : なし
//—————————————————————————–
void CAdjustDate::CalPeriodMMDD(long lFromYmd, long lToYmd, int* piPeriodMm, int* piPeriodDd)
{
long lFromYy;
long lFromMm;
long lFromDd;
long lFromEndDay;
long lToYy;
long lToMm;
long lToDd;
long lToEndDay;
long lTmp;
lFromDd = (lFromYmd % 100L);
lTmp = (lFromYmd – lFromDd) / 100L;
lFromMm = (lTmp % 100L);
lFromYy = (lTmp – lFromMm) / 100L;
lFromEndDay = (long)GetMonthEndDay((int)lFromYy, (int)lFromMm);
lToDd = (lToYmd % 100L);
lTmp = (lToYmd – lToDd) / 100L;
lToMm = (lTmp % 100L);
lToYy = (lTmp – lToMm) / 100L;
lToEndDay = (long)GetMonthEndDay((int)lToYy, (int)lToMm);
*piPeriodMm = (lToYy * 12 + lToMm) – (lFromYy * 12 + lFromMm);
if ((((lFromDd == lFromEndDay) && (lToDd == lToEndDay || lFromDd < lToDd))) ||
(lFromDd == lToDd)) {
*piPeriodDd = 0;
}
else if (lFromDd lToYmd) {
return 0L;
}
lFromDd = (lFromYmd % 100L);
lTmp = (lFromYmd – lFromDd) / 100L;
lFromMm = (lTmp % 100L);
lFromYy = (lTmp – lFromMm) / 100L;
lFromEndDay = (long)GetMonthEndDay((int)lFromYy, (int)lFromMm);
lToDd = (lToYmd % 100L);
lTmp = (lToYmd – lToDd) / 100L;
lToMm = (lTmp % 100L);
lToYy = (lTmp – lToMm) / 100L;
if (lFromYy == lToYy && lFromMm == lToMm) {
return (lToDd – lFromDd);
}
lTotalDay = lFromEndDay – lFromDd; // 今月の残日数
// 翌月へ
if (lFromMm == 12L) {
lMonth = 1L;
lYear = lFromYy + 1L;
}
else {
lMonth = lFromMm + 1L;
lYear = lFromYy;
}
// 今年の残日数
if (lYear < lToYy && lMonth != 1L) {
for (; lMonth <= 12L; lMonth++) {
lTotalDay += (long)GetMonthEndDay((int)lYear, (int)lMonth);
}
lYear++;
lMonth = 1L;
}
// 1年間の日数
for (; lYear < lToYy; lYear++) {
lTotalDay += (365L + ChkLeapYear((int)lYear));
lMonth = 1L;
}
// 最終年の日数
for (; lMonth lNowTime)
{
// [現在時刻 < 指定時刻]のとき
// 求める年月日は、今日
lAdjustYmd = _timeNow.wYear * 10000L + _timeNow.wMonth * 100L + _timeNow.wDay;
}
else
{
// [指定時刻 <= 現在時刻]のとき
// 求める年月日は、、指定の経過日数後
lAdjustYmd = AdjustDay(_timeNow.wYear, _timeNow.wMonth, _timeNow.wDay, _defSpnDay, '+');
}
return lAdjustYmd;
}
//—————————————————————————–
// 1.関数名 : AdjustMonthWithTime
// 2.機能 : 現在日時と対象日/対象時刻から、「今日」か「今月の翌日以降」か「指定月数後」の年月日を作成する
// 3.引数 : _timeNow 現在日時
// : _defSpnMonth 調整月数
// : _iTargetDd 対象日
// : _lTargetTime 対象時刻
// 4.戻り値 : 調整後の年月日
//—————————————————————————–
long CAdjustDate::AdjustMonthWithTime(SYSTEMTIME& _timeNow, int _defSpnMonth, int _iTargetDd, long _lTargetTime)
{
long lAdjustYmd;
int endDay = GetMonthEndDay(_timeNow.wYear, _timeNow.wMonth); // 今月末日
int dispDay = _iTargetDd;
if (endDay < _iTargetDd)
{ // [今月の末日 lNowTime)
{
// [現在時刻 < 指定時刻]のとき
// 求める年月日は、今日
lAdjustYmd = _timeNow.wYear * 10000L + _timeNow.wMonth * 100L + _timeNow.wDay;
}
else
{
// [指定時刻 = difference) ? difference + 7 : difference;
// 日数調整
lAdjustYmd = AdjustDay(_timeNow.wYear, _timeNow.wMonth, _timeNow.wDay, spnDay, ‘+’);
}
return lAdjustYmd;
}
//—————————————————————————–
// 1.関数名 : MostRecentMonth
// 2.機能 : 指定日の月単位での直近の年月日を作成する
// 3.引数 : _timeNow 現在日時
// : _iTargetDd 対象日
// : _lTargetTime 対象時刻
// 4.戻り値 : 調整後の年月日
//—————————————————————————–
long CAdjustDate::MostRecentMonth(SYSTEMTIME& _timeNow, int _iTargetDd, long _lTargetTime)
{
long lAdjustYmd;
if (_iTargetDd < _timeNow.wDay)
{
// 指定日は過ぎているので、翌月
// 月数調整
lAdjustYmd = AdjustMonth(_timeNow.wYear, _timeNow.wMonth, _iTargetDd, 1, '+');
}
else
{
// 今月のとき
lAdjustYmd = AdjustMonthWithTime(_timeNow, 1, _iTargetDd, _lTargetTime);
}
return lAdjustYmd;
}
//—————————————————————————–
// 1.関数名 : MostRecentMonth
// 2.機能 : 指定月日の年単位での直近の年月日を作成する
// 3.引数 : _timeNow 現在日時
// : _iTargetMm 対象月
// : _iTargetDd 対象日
// : _lTargetTime 対象時刻
// 4.戻り値 : 調整後の年月日
//—————————————————————————–
long CAdjustDate::MostRecentYear(SYSTEMTIME& _timeNow, int _iTargetMm, int _iTargetDd, long _lTargetTime)
{
long lAdjustYmd;
// 今年内過去日判定
if (_iTargetMm * 100 + _iTargetDd < _timeNow.wMonth * 100 + _timeNow.wDay)
{
// 指定月日は過ぎているので、直近は翌年
// 月数調整
lAdjustYmd = AdjustMonth(_timeNow.wYear, _iTargetMm, _iTargetDd, 12, '+');
}
else
{
// 今月か?
if (_iTargetMm != _timeNow.wMonth)
{
// 今月以外のとき、年内
// 月数調整
lAdjustYmd = AdjustMonth(_timeNow.wYear, _timeNow.wMonth, _iTargetDd, _iTargetMm – _timeNow.wMonth, '+');
}
else
{
// 今月のとき
lAdjustYmd = AdjustMonthWithTime(_timeNow, 12, _iTargetDd, _lTargetTime);
}
}
return lAdjustYmd;
}