• 締切済み

Calendar型を使用して日付の差を求めるには?

全てCalendar型です。 calA.set(2008, 1, 02, 07, 12, 0); calB.set(2008, 1, 03, 0, 0, 0); calC ←calAとcalBの差を入れたい calD.set(2008, 1, 05, 0, 0, 0); calAの2008年2月2日の7時12分から calBの2008年2月3日の0時までの差(16時間48分)の求めて calCに求めた値を入れたい。 calDにはcalCに入っている値を加算したい。 まずはcalBとcalAをgetTimeInMillisで計算するのかな?と思って やってみたのですが結果は、Fri Jan 02 01:48:00 JST 1970となりました。 (getTimeも試してみましたが、こちらはエラーとなりました。) Calendar型を使用して日付の加算や減算方法を教えていただけないでしょうか?

みんなの回答

  • HarukaV49
  • ベストアンサー率53% (48/89)
回答No.4

java言語に限らず、私の知る限り全てのプログラミング言語、 アプリケーションが、時刻の概念と時間の概念を区別していないために 難しくなっているのだと思います。 どういうことかというと、日常的に  (時間)-(時間)=(時間)  (時間)+(時間)=(時間)  (時間)×(定数)=(時間)  (時間)÷(定数)=(時間)  (時間)×(時間)=無意味  (時間)÷(時間)=(定数)  (時刻)-(時刻)=(時間)  (時刻)+(時刻)=無意味  (時刻)-(時間)=(時刻)  (時刻)+(時間)=(時刻)  (時刻)×(定数)=無意味  (時刻)÷(定数)=無意味  (時刻)×(時間)=無意味  (時刻)÷(時間)=無意味  (時刻)×(時刻)=無意味  (時刻)÷(時刻)=無意味 であることが、分かると思います。 しかしながら、java言語を含むプログラミング言語では、  (時刻)-(時刻)=(時刻) となってしまっています。 より具体的にjavaの例で言えば、  (Calendarクラス)-(Calendarクラス)=(TimePeriodクラス) でなければならないわけですが、  (Calendarクラス)-(Calendarクラス)=(Calendarクラス) となっています。また、javaにはTimePeriodクラスはありません。 日常的な例を挙げれば、  (1)時給850円で、8時間20分働いたときの給与額はいくらですか?  (2)一ヶ月の勤務規定時間が160時間のとき、一日7時間40分,20日間    働いたときの不足分は何時間何分ですか? というような計算を、Calendarクラスで実装するのは間違った方法であると 言うことです。Calendarクラスはあくまでも時刻を表していますので (1)の計算のように時刻を定数倍すると変な値になってしまいますし、 負の時刻の概念はないので、上記の(2)の例のようなマイナスの時間を 表現したりすることは出来ない訳です。 これは、エクセル等の表計算アプリケーションでも同じ問題に出くわします。 javaの場合には、時間を表すTimePeriodクラスがどこかにありそうにも思うのですが、 残念ながら私はそれを実装した例を見たことがありません。 私の想像では、欧米人は時刻と時間の概念の区別があいまいなのかなと思っています。 というわけで、独自にTimePeriodクラスを実装する必要がありそうなのですが、 初心者の方にとっては非常に難しい問題ですので、とりあえず、この問題点を 理解したうえで、とりあえずはlong型の整数の時間を使って計算する方法をお勧めします。 入出力部を除いては、時間をプリミティブな定数として処理するという方法です。 (入出力部では、Calendarクラスをごまかして時間の表現に使います)

全文を見る
すると、全ての回答が全文表示されます。
  • auty
  • ベストアンサー率58% (284/486)
回答No.3

日付の計算は、数値のようには簡単に出来ません。 60分、24時間などが現れます。 つまりintやlongだけで処理をしようとするとそのたびに複雑なプログラミングを組まなければなりません。 そこでjavaの場合、日付の計算として、    DATE型やCalendar型が用意されています。 日時を「ある基点となる時間からの経過したミリ秒」として扱えば、その日時の差は、経過ミリ秒としてあつかうことが出来ます。この場合普通long型として処理できますし多くの言語等でも採用されています。 DATE型は、主にこの考え方に基づいて作られていますが、あくまでクラスですから直接引き算は出来ません。メソッドをつかって、ミリ秒を取得する必要があります。 さて、Calendar型ですがこれも「ある基点となる時間からの経過したミリ秒」の情報を維持するクラスですが、時間差を維持するものではありません。 したがって、直接Calendar型の差を求めることは出来ません。時間差を求めるには、まずそのメソッドを使って経過したミリ秒を求めてからということになります。 その結果の時間差は、Calendar型ではあつかえませんので代入できません。 日付(calD)の何日後というのは求められますが、日付(calD)の日付(calC)後というのは出来ません。calCに時間差を保存していると勘違いしているからでしょう。 図式的に書くと -------------------------------------------------- ・ 日付+日付:   ダメ ・ 日付-日付:   直接はダメでメソッドを使う ・ 日付の何日後: 直接はダメでメソッドaddを使う ・ 日付の何日前: 直接はダメでメソッドaddを使う -------------------------------------------------- いづれにしても慣れるのにちょっと時間はかかるかと思いますが Calendar型 に挑戦してください。

全文を見る
すると、全ての回答が全文表示されます。
  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.2

差をCalendarオブジェクトで得るためには、computeTime(), computeFields(), そして必要ならcomplete()メソッドを使います。 加算減算はadd()メソッドで十分です。

全文を見る
すると、全ての回答が全文表示されます。
  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

>calC ←calAとcalBの差を入れたい 日付の差は Calendar オブジェクトにはならないので、秒数などで計算するしかないでしょう。 >calDにはcalCに入っている値を加算したい。 calD に指定の秒数を足せばよいはずです。

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

関連するQ&A

  • calendarクラスの使い方について

    時間データ(h:mm:ss)のみの差を求める場合に calendarクラスを利用しましたが 20時32分50秒というデータを cal.get(20,32,50)と記述して以下の プログラムを実行しても ---------結果 差:4838400 となりうまくいきません。 型があってないので、当然といえば当然かもしれませんが・・・ 本当は時刻、分、秒だけのデータで 差:115 と計算し表示させたいのです。 どうやったら、 2004,5,16,20,32,50 ではなく、 20,32,50の情報だけで時間と時間の差を 取得できるでしょうか 他の方法が思いつきませんので どなたかご存知であれば教えてください。 よろしくお願いします ---------プログラムリスト import java.util.Calendar; import java.util.Date; public class TestDate{ public static void main(String[] args){ Calendar cal1 = Calendar.getInstance(); cal1.set(2004,5,16,20,32,50); Date dat = cal1.getTime(); long date1 = dat.getTime(); Calendar cal2 = Calendar.getInstance(); cal2.set(2004,5,16,20,34,45); long date2 = cal2.getTime().getTime(); long distance = (date2 - date1) / (1000); System.out.println("差:"+distance); } } -----------------------------------------

    • ベストアンサー
    • Java
  • Calendarクラスの日付更新について

    ある日付を追加した時,うまく正式な日付になりません。 (1) 2002年9月30日にセットする (2) 1日追加する --→この時点で2002年9月31日になっている。 (3) 10月1日に正式な日付に直す という流れなのですが・・・ ソースは以下のとおりです。 public static void main(String[] args) {        Calendar cal = new GregorianCalendar();     /*(1)*/     cal.set(2002,9,30);    /*(2)*/     cal.add(Calendar.DATE,1); /*(3)*/ cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DATE) ); System.out.println(cal.get(Calendar.YEAR) "年"+ cal.getCalendar.MONTH) +"月"+ cal.get(Calendar.DATE) +"日"); } と、表示させると2002年10月1日になっておらず2002年9月31日になったままです。 これはどこに原因があるのでしょうか?ご指導お願いします。

    • ベストアンサー
    • Java
  • Java CDLC 1.0 での日付計算

    CLDC(携帯向けJava)での日付計算がうまくいきません。 JavaのSEでは、Calender.addなる日付計算関数があるようですが、 CLDC(携帯向けJava)では使えないみたいなので、以下の実験コードを 書いてみました。しかし、意図する結果が得られませんでした。 このケースでのよい計算方法をご存知でしたらご教授 頂ければうれしく思います。または、 以下のプログラムのバグ、ポカアホミス、作法的要修正点、 日付計算仕様的な可能/不可能等お気づきありましたら、 ご指摘頂ければ嬉しいです。 尚、意図した結果とは、下記の★部分において、 1970年1月1日(?曜日) 0:1:0 です。 グリニッジ標準時 1970 年 1 月 1 日 0:00:00 (エポック) からの 経過時間が、60000ミリ秒(60秒) というのを期待しました。 --以下コード-- void print_cal(Calendar cal){ String WEEK=" 日月火水木金土"; int year =cal.get(Calendar.YEAR); int month =cal.get(Calendar.MONTH)+1; int day_of_month=cal.get(Calendar.DAY_OF_MONTH); int day_of_week =cal.get(Calendar.DAY_OF_WEEK); int hour =cal.get(Calendar.HOUR_OF_DAY); int minute =cal.get(Calendar.MINUTE); int second =cal.get(Calendar.SECOND); System.out.println("" + year + "/" + month + "/" + day_of_month + "(" + WEEK.charAt(day_of_week) + ") " + hour + ":" + minute + ":" + second); } Calendar cal = Calendar.getInstance(); long now = cal.getTime().getTime(); print_cal(cal); cal.set(Calendar.YEAR, 2007); cal.set(Calendar.MONTH, Calendar.MAY); cal.set(Calendar.DAY_OF_MONTH, 31); cal.set(Calendar.HOUR_OF_DAY, 6); cal.set(Calendar.MINUTE, 12); cal.set(Calendar.SECOND, 44); print_cal(cal); //<---- 2007/5/31(木) 6:12:44 long time1 = cal.getTime().getTime(); cal.set(Calendar.YEAR, 2007); cal.set(Calendar.MONTH, Calendar.MAY); cal.set(Calendar.DAY_OF_MONTH, 31); cal.set(Calendar.HOUR_OF_DAY, 6); cal.set(Calendar.MINUTE, 13); cal.set(Calendar.SECOND, 44); long time2 = cal.getTime().getTime(); print_cal(cal); //<------ 2007/5/31(木) 6:13:44 long sabun = time2 - time1; //<---- 60000 Date hoge = new Date(sabun); long hoge_time = hoge.getTime(); System.out.println(hoge_time); <--- 60000 //setTime: Calendar の現在の時刻を、指定された Date に。 cal.setTime(hoge); //★この時点でprint_cal。 print_cal(cal); <---- 1970/1/1(木) 9:1:0 ?9時間も経ってる? long now2 = cal.getTime().getTime(); System.out.println("now2: " + now2); <--- 60000。でも60秒がはいってるぽい --コード以上--

    • ベストアンサー
    • Java
  • 週単位の日付の加算

    すみませんが、どなたか教えて下さい。 日付の加算を4週間後、というような日付の加算をしたいのですが、 28日や31日の月があった場合、ずれてしまいます。 どのようにしたら正確なカレンダー通り加算ができるでしょうか? 「20060404」の結果が欲しいが下記だと、「20060405」となってしまう。 Calendar cal = Calendar.getInstance(); cal.set(2006,3,7); int plus = 7*4; //7日×4週間 cal.add(Calendar.DATE, plus);

    • ベストアンサー
    • Java
  • 「分」単位で加算(減算)したい。

    「分」単位で加算(減算)したい。 y1=2010; //西暦 m1=7; //月 d1=6; //日 h1=10; //時 n1=30; //分 s1=0; //秒 のような特定の日時に対して、 例えば、「1000分加算(或いは減算)した『日時』」 という風に、「分」単位で加算・減算したいのですが、 やり方がわかりません。 基本的な操作かもしれませんが、どなたかご教授お願いします。 なお、日数での加算・減算は対処できております。 ↓====================================- var dt = new Date( y1, m1-1, d1); //元となる日付 var addSec = 86400000; var newDate = new Date(); newDate.setTime( dt.getTime()+addSec ); myYear = newDate.getYear(); myYear4 = (myYear < 2000) ? myYear+1900 : myYear; myMonth = newDate.getMonth()+1; myDate = newDate.getDate(); ↑====================================-

  • 日付・時間について

    e-mailの日付、時間に関する質問です。 例えば、次のように受信したとします。(実際のものなんですが) To: ****@yahoo.co.jp Subject: Re: Guten tag! Date: Fri, 24 Jan 2003 18:34:08 +0100 「Date」にある18:34:08はそれぞれ”時、分、秒”を表しているのだと思いますが +01001とは何を表しているのでしょうか? あと、これは受信した時間を表示しているのでしょうか?(まさか相手が送信した時間とかではないですよね。) 以上取るに足らない質問かも知れませんがよろしくお願いします!

  • カレンダークラス

    入力値の日付から1年後の日付をもとめたいのですが、よく分かりません。 入力値は XXXX年 XX月 XX日 のような感じです。 Calendar cal1 = Calendar.getInstance(); cal1.set(int,int,int);で上記で入力された値をint型にして設定し、 その後に、cal1.add(Calender.YEAR,1); としています。 なのですが、なぜだか1ヶ月進んだ値が返却されます、、 2009/01/01なら2010/02/01が返却される。 また現在日付を取得して表示しても1ヶ月進んで表示されるのですが、、 どなたか詳しい方教えて下さい。宜しくお願いします。

    • ベストアンサー
    • CGI
  • java.util.CalendarでのgetTime結果

    お世話になります。 カレンダークラスを使用してDBへ格納するためのシリアル値を取得しようとしています。 やりたいことは任意の年月日(時分秒は無し)をPostgreSqlのDATEフィールドに日付として格納させ、レコード取得した結果の該当DATEフィールドと先ほどの任意の年月日を比較させたいのです。予想される結果は「一致」なのですがこれが不一致となってしまいます。 例えばjava.util.CalenderクラスのgetTime()を使用して取得されるシリアル値は1174611700734ですが、DBへ格納された後にレコードから取得されるデータは1174575600000となっていて比較しても不一致となってしまいます。 java.util.CalenderのgetTime()結果は実行するたびに値が異なるようで、下3桁が上記例のように"734"だったり"015"だったりします。 getTime()の結果で返されるシリアル値の下3桁を"000"とする方法はあるのでしょうか? java.util.Calendar xcal = java.util.Calendar.getInstance(); xcal.set(2007, 3 - 1, 23, 0, 0, 0); java.util.Date xday = xcal.getTime(); #xdayには"1174575600015"と格納されています。 #xdayをそのままPostgreSqlへデータ投入すると、日付のみ格納され次回取得時には"1174575600000"となります。

    • ベストアンサー
    • Java
  • Calendarクラスについて

    java勉強中の初心者です。 現在、カレンダークラスの勉強をしています。 いろいろ試しているのですが、お聞きしたいこと があります。 末日を取得するgetActualMaximumメソッドですが Calendar cl = Calendar.getInstance(); int lastDay = cl.getActualMaximum(Calendar.DATE); でその月の末日を取得できることがわかりましたが 応用で、1年間の(1月~12月)すべてを取得するときに -------------------------------------------------- Calendar cl = Calendar.getInstance(); for(int n = 1; n<=12; n++){ cl.set(2005,12+n,1); cl.add(Calendar.DAY_OF_MONTH,1); cl.set(cl.get(Calendar.YEAR),cl.get(Calendar.MONTH),cl.getActualMaximum(Calendar.DATE)); System.out.println(cl.get(Calendar.YEAR) +"年"+ cl.get(Calendar.MONTH ) + "月"+ cl.getActualMaximum(Calendar.DATE) +"日"); } } } ------------------------------------------------- 月は「0」から始まるということは理解できたのですが これだと実行結果が 2006年1月28日 2006年2月31日 2006年3月30日 2006年4月31日 2006年5月30日 2006年6月31日 2006年7月31日 2006年8月30日 2006年9月31日 2006年10月30日 2006年11月31日 2007年0月31日 ---------------------------------------------- となってしまうのですが、一番初めが2月の 末日を取得してしまっているのはわかっているのですが どこを直せばよいのかわかりません。 ご教授お願いできますか? よろしくお願いいたします。

    • ベストアンサー
    • Java
  • Calendarオブジェクトにタイムゾーンの設定

    Calendarクラスで不思議に思ったことがあったので質問させてください。 下記サンプルのようにCalendarオブジェクトに対してタイムゾーンを設定しました。 表示1ではGMTタイム(9時間前の時間)が表示。 表示2では現在の時刻(設定したタイムゾーンを無視) して表示されてしまいます。これは仕様でしょうか。 JavaDocのなかで下記記述を見つけたのですがこの記述と関係ありますでしょうか。 いまいち文章が難解でよくわからないのですがgetメソッドなら計算した値 (この場合、タイムゾーンを反映して計算した値)を返しますよ と言っているのかなと 思ったのですが違いますでしょうか。 【JavaDocの記述】 「カレンダフィールド値は、set メソッドを呼び出して設定できます。 Calendar 内で設定されたフィールド値はすべて、その時間値 (「元期」からのミリ秒) または カレンダフィールドの値を計算する必要が生じるまで解釈されません。 get、getTimeInMillis、getTime、add、および roll の呼び出しでは、この種の計算が行われます。」 【サンプル】 Calendar cal = Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone("GMT")); //表示1 System.out.println(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + "-" +          cal.get(Calendar.DAY_OF_MONTH) + " " +          cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" +          cal.get(Calendar.SECOND)); //表示2 System.out.println(cal.getTime().toString());