• 締切済み

期間の計算

SQLされたある開始日、終了日がn個あり、それらのトータルの期間の合計を求めます。単純に一つ一つの期間を出して全部足すのではなく、重なっている部分を取り除きたいのですが解法が見出せません。よろしくお願いします。西暦、月はそれぞれint形に変換しております。   例     n   開始日   終了日  1  2000/1   2005/2  2  2003/2   2004/8  3  2004/8   2005/5 4 2005/10 2005/12  1の期間は5年1ケ月、2の期間は1年6ヵ月 3の期間は9ヶ月です。4の期間は2ヶ月重なっている期間や空白の期間を省くトータルの期間は5年6ヵ月となります。この5年6ヵ月を求めるアルゴリズムが思いつきません。よろしくお願いします。なおのnはwhile(rs.next()){ } でループしています。

みんなの回答

  • takaP-
  • ベストアンサー率79% (83/105)
回答No.1

う~ん、多分これには定石みたいなのがあると思うんですよ。。。が!いかんせん無学な私はそれを知りません。 取り敢えず思い付いたやり方を書きますんで、それを土台に改良なりをしてみて下さい(それでも回答が無いよりはマシでしょうから・w) まずは、年と月をそれぞればらばらにして保持しているようですが、面倒なのでまとめてしまいましょう。 総月数 = 年×12+月 例) int n1_top = 2000 * 12 + 1 ; //開始日 int n1_tail= 2005 * 12 + 2 ; //終了日 次は、2重配列を作ります 例) int[][] array={{n1_top,n1_tail},{n2_top,n2_tail}・・ {n*_top,n*_tail}}; 次は、今作った2重配列をソートしてしまいます。 多重配列のソートに関しては丁度、最近ここの掲示板で話題がありましたので、それを参照して下さい。 http://www.okweb.ne.jp/kotaeru.php3?q=603859 ソートは n*_top(開始日)の値の比較で小さい順に並べ替えます。 次に、下記の処理を加えます。 例) for(int i=0; i<array.length-1; i++){   if(array[i][1]>array[i+1][0]){     array[i+1][0]=array[i][1] ;     if(array[i][1]>array[i+1][1]){       array[i+1][1]=array[i][1];     }   } } やっている事は、前回の終了日と次回の開始日を比較し、もし、終了日よりも開始日が早ければ(日数が被っていれば)次回の開始日を「前回の終了日の値」へと変更すし、かつ、次回の終了日が前回の終了日よりも早ければ、同様に「前回の終了日の値」へと変更しています。 これにより、重複している部分は排除されるはずです。 そして、目的の「重なっている期間や空白の期間を省くトータルの期間」を求める時は、もう重複部分はありませんので 例) int ans=0; for(int i=0; i<array.length; i++){   ans+=array[i][1]-array[i][0]; } とかする事で、期間が求まると思います(たぶんですが・汗 こればベストだとは『とても、とても』口が裂けても言えませんが、どうしても良案が思いつかないのでご勘弁を。 もう少し回答待ちをして、経験者の方のアドバイスを求めた方が良いでしょう。

tacch
質問者

お礼

takaさん回答ありがとうございます。二重配列を利用すると考えやすくなりますね。takaさんの回答をお手本に自分でも考えて見ます。ありがとうございました!

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • エクセルによる残期間の計算

    ある日からある日までの残期間を示す関数を探して います。 例) 開始日 2003/12/01 終了日 2005/04/01 上記のような場合の残期間数ってどのように 出すのでしょうか? 示される答えとして、「○年▲ヶ月」と 出したいのですが・・・

  • 期間計算式を教えてください

    EXCELでの期間計算式を教えてください  例として2003年7月12日から2007年9月3日までの期間を何年何ヶ月と表示させる計算式を入力したいのですが、下記の計算式を入力すると「一ヶ月未満」が切り捨てられてしましまい、5年1ヶ月と表示されます。一ヶ月に満たない月も一ヶ月とする計算式を作成したいと思っています。例題であれば、5年3ヶ月と表記できる計算式を教えてください。  (始まりの期間をA1に終了をB1にそれぞれ記入し 期間をC1に表示させています。) =DATEDIF(A1、B1,"Y")&"年"&DATEDIF(A1,B1,"YM")&"カ月"  お願いします。

  • Accessクエリーにて開始日と終了日から期間を算出

    Accessのクエリーにて、開始日と終了日から該当月の貸し出し期間の算出方法を教えて下さい。 条件ですが、 月単位での算出の為、1ヶ月は「1」、半月は「0.5」で算出します。 当月に開始された明細では、 15日までに開始されれば1ヶ月で算出 16日以降に開始されれば半月で算出 当月に終了された明細では、 15日までに終了されれば半年で算出 16日以降に終了されれば1ヶ月で算出 同月内に開始・終了の場合は1ヶ月で算出 貸し出し中の明細の場合、「終了日」はNULLです。 算出年月 200712の場合のデータは下記の通りです 「算出年月」、「開始日」、「終了日」、 200712、20071210、、、期間は「1」 200712、20071220、、、期間は「0.5」 200712、20050505、20071219、期間は「1」 200712、20061222、、、期間は「1」 200712、20071201、20071210、期間は「1」 宜しくお願い致します。

  • 指定した期間の日付生成

    任意の期間(自~至)を指定して、 その間の日付を1日単位で取得したいのですが うまい方法が思いつきません。 こうすれば簡単だというアルゴリズムがあれば 教えてください。 例) 開始日 $start '2005/06/29' 終了日 $end '2005/07/02' というデータがあれば 2005/06/29 2005/06/30 2005/07/01 2005/07/02 を取得したいのです。

    • ベストアンサー
    • PHP
  • エクセルで期間から期間を足したり引いたりする方法を教えてください

    期間から期間を引く計算方法を教えてください ○年○ヵ月○日から○年○ヵ月○日を引いて○年○ヵ月○日を表示する方法を教えてください。 たとえば、勤続年数が31年6ヵ月15日(A1)で休職期間が1年8ヶ月21日(A2)あった場合、実際に勤務についていた日数を祭日に関係なく、○年○ヵ月○日(A3)と表示させたい。 入社日  昭和52年9月16日 退社日  平成21年3月31日 在籍期間  31年6ヵ月15日 休職開始日 平成18年1月8日 休職終了日 平成19年9月29日 休職期間   1年8ヶ月21日 期間計算の方法はEXCELのDATEDIF関数で出してます。 期間同士を足したり引いたりする方法を教えてください。

  • JavaScriptで期間を計算したい。

    ある期間(複数)を入力したら、その合計を表示させたいのですが、 良い方法はないでしょうか。よろしくお願いします。 サンプルはこのような感じです。 ------------------- 期間1: 西暦 <input name="kikan01_01" type="text" id="kikan01_01" />年 <input name="kikan01_02" type="text" id="kikan01_02" />月 ~ 西暦 <input name="kikan01_03" type="text" id="kikan01_03" />年 <input name="kikan01_04" type="text" id="kikan01_04" />月 期間2: .... 期間3 .... 合計年数 <input name="nensuu" type="text" id="nensuu" />年 <input name="kagetsu" type="text" id="kagetsu" />ヶ月

  • デジタル時計のアルゴリズム

    こんばんは。私は、プログラミングを学ぶ社会人です。現在研修中の身です。 デジタル時計のアルゴリズムを考えていまして、とりあえず無限ループさせればいいのかな?と思いました。 ところで、無限ループさせるためのアルゴリズムって、どのように書けばよろしいのでしょうか? 例えば大まかに言うと「変数TIME→0」と書いた後で、 ループ開始 | TIME+1→TIME | ループ終了 (※「|」は下に向かうフローです。) と記述し、終了条件を何も書かなければ、それで無限にループされることになるのでしょうか? ご回答よろしくお願い致します。

  • 期間集計を日別集計にしたい

    DBはアクセス(.mdb)です。 現在のSQL構文です。。。 strSQL = "SELECT COUNT (*) From DB1 " strSQL = strSQL & "where 条件その1 = '" & Form1.Text1.Text & "' " strSQL = strSQL & "AND 条件その2 = '" & Form1.Text1.Text & "' " strSQL = strSQL & "AND 日時 BETWEEN #" & (開始日時を格納した変数) & "# AND #" & (終了日時を格納した変数) & "#" rs.Open strSQL, cn SU = rs.Fields(0).Value 上記のPGで変数「SU」に、SQL文で設定した条件に該当 するレコード数を代入していますが、これではあくまで 開始日時と終了日時の間に存在するトータルレコード数 、言わば「期間合計」になってしまいますよね。 現在行いたい内容ですが、開始日時と終了日時の間の日 付を1日ごとに分割し、その1日ごとでのレコード数が分 かる、「日別合計」処理をさせるようにしたいのですが。 やっぱり上記のSQL文を根本から考え直さないと出来ない でしょうか?出来れば、なるべく残しつつ、後の方で加工 できればいいなぁと思っているんですが。。。 よろしくお願いします。

  • エクセル関数で期間を何年何ヶ月と求めたいのですが

    エクセル関数で期間を何年何ヶ月と1個のセルに求めたいのですが =datediff(開始日,終了日,"Y")で年は求められたのですが これを何年何ヶ月と1つのセルに表示させたいのですがわかりませんでした。 わかる方、宜しくお願い致します。

  • 試用期間は職歴に計算するのでしょうか?

    早期出社として入社より前に3ヶ月試用期間がありました。 履歴書に職歴を記入する際には、入社日を試用期間開始日にすべきでしょうか? それとも本採用となった3ヶ月後を入社日と書くべきでしょうか?

このQ&Aのポイント
  • CANONプリンターG6030のカセットからの印刷が突然できなくなってしまった問題について、解決方法を教えてください。
  • 10月8日、CANONプリンターG6030でカセットからの印刷ができなくなりました。パソコンから印刷指定してもメッセージが表示され、カセットを指定できない状態です。解決方法を教えてください。
  • CANONプリンターG6030でカセットからの印刷ができなくなった問題について、Macbook Airを使用しています。電源を外して再設定しても解決しません。どうすれば解決できるでしょうか。
回答を見る