日付の差を求めるメンバ関数

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ゆう
記事: 3
登録日時: 10年前

日付の差を求めるメンバ関数

#1

投稿記事 by ゆう » 10年前

うるう年は考慮せず、メンバ関数subの引数として渡される日付が古いものであるとした時に日付の差を求めるプログラムです。
ループを用いてyear、month、dayが等しくなるまでループしその回数を差分として出力したいです。
なのですが通してもメンバ関数subの中身がうまくかけず困っています。
お力を貸してください。

コード:

 
#include<iostream>
using namespace std;
class Date{
private:
 int year;
 int month;
 int day;
 int i;
public:
 Date(int y, int m, int d){
  year=y;
  month=m;
  day=d;
  switch(month){
  case 1:
  case 3:
  case 5:
  case 7:
  case 8:
  case 10:
  case 12:
   if(day>31){
   year=month=day=0; 
   }
   break;
  case 4:
  case 6:
  case 9:
  case 11:
   if(day>30){
   year=month=day=0; 
   }
   break;
  case 2:
   if(day>28){
   year=month=day=0; 
   }
   break;
  default:
   year=month=day=0;
   break;
  }
 }
 void next(){
  day=day+1;
  do{
   switch(month){
   case 1:
   case 3:
   case 5:
   case 7:
   case 8:
   case 10:
   case 12:
    if(day>31){ day=day-31;
    month=month+1;
    }
    if(month==13){
     month=month-12;
     year=year+1;
    }
    break;
   case 4:
   case 6:
   case 9:
   case 11:
    if(day>30){
     day=day-30;
     month=month+1;
    }
    break;
   case 2:
    if(day>28){
     day=day-28;
     month=month+1;
    }
    break;
   default:
    break;
   }
  }while(day>=32);
 }
 void get(int &y, int &m, int &d){
  y=year;
  m=month;
  d=day;
 }
 int sub(Date d){

 }
};
int main()
{
 int y[] = {2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014};
 int m[] = {8, 9, 1, 2, 1, 12, 2, 2};
 int d[] = {31, 1, 1, 28, 1, 31, 28, 28};
 int yy, mm, dd;
 for (int i = 0; i < sizeof(y) / sizeof(int); i+=2) {
  Date d1(y[i], m[i], d[i]);
  Date d2(y[i+1], m[i+1], d[i+1]);
  d1.get(yy, mm, dd);
  cout << yy << "年" << mm << "月" << dd << "日から";
  d2.get(yy, mm, dd);
  cout << yy << "年" << mm << "月" << dd << "日までは";
  cout << d2.sub(d1) << "日です" << endl;
 }
 return 0;
}

Aozora0630
記事: 85
登録日時: 10年前
住所: 日本
連絡を取る:

Re: 日付の差を求めるメンバ関数

#2

投稿記事 by Aozora0630 » 10年前

うーん・・・。わざわざそんなことをしなくても、year、monthを何日かに変換すればいいじゃないですか・・・。

コード:

int result = day;

result += (month-1)*30;
result += year*365;
resultが総日数です。此れで比べればノープロブレム。
因みに、一月の日数は30日としています。31やら30に変えたい場合はifで作ってください。

全く、不便だよなー。グレゴリウス暦は・・・。

お望みなら→http://okwave.jp/qa/q198873.html

ゆう1

Re: 日付の差を求めるメンバ関数

#3

投稿記事 by ゆう1 » 10年前

Aozora0630様のアドバイスを元にし
メンバ関数subの中をこのようにしたところ
以前よりは進歩したのですがまだしっかりとした結果が得られません。
(2014/8/31)-(2014/9/1)の処理の時に実際は1日しか違わないのに31-1が行われてしまいます。
しばらく考えても通したらいいかわかりませんでした。

コード:

 int sub(Date d){
	
int result = day-d.day;
result += (month-(d.month-1))*30;
result += (year-d.year)*365;
return result;
 }

かずま

Re: 日付の差を求めるメンバ関数

#4

投稿記事 by かずま » 10年前

ゆう さんが書きました:うるう年は考慮せず、メンバ関数subの引数として渡される日付が古いものであるとした時に日付の差を求めるプログラムです。
ループを用いてyear、month、dayが等しくなるまでループしその回数を差分として出力したいです。

コード:

#include<iostream>
using namespace std;

class Date {
    int year, month, day;
    static int t[12];
public:
    Date(int y, int m, int d) {
        if (m < 1 || m > 12 || d < 1 || d > t[m - 1])
            year = month = day = 0;
        else
            year = y, month = m, day = d;
    }

    void next() {
        if (++day > t[month - 1]) {
            day = 1;
            if (++month > 12) {
                month = 1;
                year++;
            }
        }
     }

    void get(int& y, int& m, int& d) const {
        y = year, m = month, d = day;
    }

    int sub(Date d) {
        if (d.year > year || d.year == year && d.month > month || d.day > day)
            return -1;
        for (int days = 0; ; d.next(), days++)
            if (d.day == day && d.month == month && d.year == year) return days;
    }
};

int Date::t[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };

int main()
{
    int y[] = {2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014};
    int m[] = {   8,    9,    1,    2,    1,   12,    2,    2};
    int d[] = {  31,    1,    1,   28,    1,   31,   28,   28};
    int yy, mm, dd;
    for (int i = 0; i < sizeof(y) / sizeof(int); i += 2) {
        Date d1(y[i], m[i], d[i]);
        Date d2(y[i+1], m[i+1], d[i+1]);
        d1.get(yy, mm, dd);
        cout << yy << "年" << mm << "月" << dd << "日から ";
        d2.get(yy, mm, dd);
        cout << yy << "年" << mm << "月" << dd << "日までは ";
        cout << d2.sub(d1) << "日です" << endl;
    }
    return 0;
}
閏年も考慮して、ループも使わないやり方がありますが、知りたいですか?

ゆう2

Re: 日付の差を求めるメンバ関数

#5

投稿記事 by ゆう2 » 10年前

かずま様ソースコードありがとうございます。
そのような方法があるならばぜひ教えていただきたいです。

かずま

Re: 日付の差を求めるメンバ関数

#6

投稿記事 by かずま » 10年前

ゆう2 さんが書きました:そのような方法があるならばぜひ教えていただきたいです。

コード:

#include <iostream>
using namespace std;

int days(int y, int m, int d)
{
    static const int t[] = {306,337,0,31,61,92,122,153,184,214,245,275};
    y -= m < 3;
    return 365*y + y/4u - y/100u + y /400u + t[m-1] + d;
}

class Date {
    int year, month, day;
    static const int t[12];
public:
    Date(int y, int m, int d) {
        if (m < 1 || m > 12 || d < 1 || d > t[m-1])
            year = month = day = 0;
        else
            year = y, month = m, day = d;
    }

    void get(int& y, int& m, int& d) const {
        y = year, m = month, d = day;
    }

    int sub(const Date& d) const {
        return days(year, month, day) - days(d.year, d.month, d.day);
    }
};

const int Date::t[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };

int main()
{
    int y[] = {2014, 2014, 2014, 2014, 2014, 2014, 2014, 2014};
    int m[] = {   8,    9,    1,    2,    1,   12,    2,    2};
    int d[] = {  31,    1,    1,   28,    1,   31,   28,   28};
    for (int i = 0; i < sizeof(y) / sizeof(int); i += 2) {
        int yy, mm, dd;
        Date d1(y[i], m[i], d[i]);
        Date d2(y[i+1], m[i+1], d[i+1]);
        d1.get(yy, mm, dd);
        cout << yy << "年" << mm << "月" << dd << "日から ";
        d2.get(yy, mm, dd);
        cout << yy << "年" << mm << "月" << dd << "日までは ";
        cout << d2.sub(d1) << "日です" << endl;
    }
    return 0;
}
分からないところがありますか?
自分で調べても分からなければ、また質問してください。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 日付の差を求めるメンバ関数

#7

投稿記事 by みけCAT » 10年前

ゆう1 さんが書きました:Aozora0630様のアドバイスを元にし
メンバ関数subの中をこのようにしたところ
以前よりは進歩したのですがまだしっかりとした結果が得られません。
(2014/8/31)-(2014/9/1)の処理の時に実際は1日しか違わないのに31-1が行われてしまいます。
しばらく考えても通したらいいかわかりませんでした。

コード:

 int sub(Date d){
	
int result = day-d.day;
result += (month-(d.month-1))*30;
result += (year-d.year)*365;
return result;
 }
両方のmonthから1を引かないといけないかもしれません。(テストしていません)
オフトピック
「通したらいいかわかりませんでした」ってどういう意味だろう?
「通す」は「AC(正解)する」という意味であり、この問題に正解するまで取り組むべきか、という意味かなあ…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ゆう3

Re: 日付の差を求めるメンバ関数

#8

投稿記事 by ゆう3 » 10年前

かずま様
ありがとうざいます。理解出来ました。
こっちのほうが綺麗でいいですね。

みけCAT様
すみませんタイピングミスです。×通したら ○どうしたら です。

かずま

Re: 日付の差を求めるメンバ関数

#9

投稿記事 by かずま » 10年前

ループを使う方のプログラム の sub() の中で、引数の d の日付が古くないことを
判定するところが次のようになっていますが、これは間違っています。

コード:

    if (d.year > year || d.year == year && d.month > month || d.day > day)
        return -1;
次のように訂正します。

コード:

    if (d.year > year || d.year == year &&
        (d.month > month || d.month == month && d.day > day)) return -1;

閉鎖

“C言語何でも質問掲示板” へ戻る