質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

4回答

23183閲覧

javaである期間の経過年月日時分秒を算出したい

luckyclock

総合スコア73

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

2クリップ

投稿2016/02/25 01:18

編集2022/01/12 10:55

下記のようなStringで与えられる年月日時分秒
"2014/12/20 23:45:23"と
現在の時刻を比較し、
与えられた時刻から現在までyy年mmか月dd日 hh時間mm分ss秒経過
のように表示したいのですが、詰まってます。

わかりやすい例で行くと
下記サイトさんに時分秒を追加したような感じです。
http://keisan.casio.jp/exec/system/1177658154

追記

うるう年は考慮したいです。
月が違う場合例えば2016年1月1日~3月4日だと初日を1日目としたとすると、2か月と4日になります。
2016年2月28日~4月1日なら1か月と4日ですが、今年はうるう年なので1カ月と5日になります。
2月28日~4月28日ですと2か月と1日、2月28日~4月29日ですと2か月と2日になります。

とりあえず下記のプログラムで
大半は取得できていますが、○○日経過の
○○日の部分が出せていません。

経過月数を使って何かと引き算すれば出せそうな気がするのですが思いつきません。

java

1public class DifferenceDays { 2 public int differenceDay; //期間の全日数 3 public int differenceMonth; //期間の全月数 4 public int differenceYear; //経過年数 5 public int month; //1年未満の経過月数 6 public int day; //1か月未満の経過日数 7 public int hour; //経過時 8 public int minute; //経過分 9 public int second; //経過秒 10} 11 12public class DifferenceDaysCalc { 13 14 public DifferenceDays date; 15 16 public DifferenceDaysCalc(){ 17 date = new DifferenceDays(); 18 } 19 20 public DifferenceDays calcDay(String day){ 21 String _day; 22 Date start = null; 23 Date today = null; 24 try { 25//とりあえず固定値でテスト 26 start = new SimpleDateFormat("yyyy'/'MM'/'dd HH:mm:ss", Locale.JAPANESE).parse("2016/1/24 12:34:12"); 27 today = new SimpleDateFormat("yyyy'/'MM'/'dd HH:mm:ss", Locale.JAPANESE).parse("2016/1/25 00:10:00"); 28 // SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 29 // String str = format.format(new Date()); 30 // today = format.parse(str); 31 } 32 catch (Exception e) { 33 } 34 date.differenceDay = differenceDays(today, start); //経過日数 35 date.differenceMonth = differenceMonth(today, start); //経過月数 36 date.differenceYear = date.differenceMonth / 12; //経過年数 37 date.Month = date.differenceMonth % 12; //1年未満の経過月数 //1年未満の経過月数 38 //1か月未満の経過日数 39 date.hour = differenceHours(today, start); //経過時 40 date.minute = differenceMinute(today, start); //経過分 41 date.second = differenceSecond(today, start); //経過秒 42 return date; 43 } 44 45 public static int differenceDays(Date date1,Date date2) { 46 long datetime1 = date1.getTime(); 47 long datetime2 = date2.getTime(); 48 long one_date_time = 1000 * 60 * 60 * 24; 49 long diffDays = (datetime1 - datetime2) / one_date_time; 50 return (int)diffDays; 51 } 52 53 public static int differenceHour(Date date1,Date date2) { 54 long datetime1 = date1.getTime(); 55 long datetime2 = date2.getTime(); 56 long diffHour = (datetime1 - datetime2) / 1000 / 60 / 60 % 24; 57 return (int)diffHour; 58 } 59 60 public static int differenceMinute(Date date1,Date date2) { 61 long datetime1 = date1.getTime(); 62 long datetime2 = date2.getTime(); 63 long diffMinute = (datetime1 - datetime2) / 1000 / 60 % 60; 64 65 return (int)diffMinute; 66 } 67 68 public static int differenceSecond(Date date1,Date date2) { 69 long datetime1 = date1.getTime(); 70 long datetime2 = date2.getTime(); 71 long diffSecond = (datetime1 - datetime2) / 1000 % 60; 72 return (int)diffSecond; 73 } 74 75 public static int differenceMonth(Date date1, Date date2) { 76 Calendar cal1 = Calendar.getInstance(); 77 cal1.setTime(date1); 78 cal1.set(Calendar.DATE, 1); 79 Calendar cal2 = Calendar.getInstance(); 80 cal2.setTime(date2); 81 cal2.set(Calendar.DATE, 1); 82 int count = 0; 83 if (cal1.before(cal2)) { 84 while (cal1.before(cal2)) { 85 cal1.add(Calendar.MONTH, 1); 86 count--; 87 } 88 } else { 89 count--; 90 while (!cal1.before(cal2)) { 91 cal1.add(Calendar.MONTH, -1); 92 count++; 93 } 94 } 95 return count; 96 } 97}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takotakot

2016/02/25 05:06

月が違う場合日付をどうとらえるか、具体例が数個ないと回答が示せません。 1月1日から3月4日や 2月28日から4月1日、4月28日、4月29日 うるう年が挟まるかどうかで数え方を変えるかどうか。 それらをどう数えたいか具体的に質問に書かなければなりません。
swordone

2016/02/25 08:37

経過時間を計算しようとしているのに、初日で1日目とカウントしていいのですか?始点と終点を同じ日時にした場合でも「1日」という扱いになりますが。
luckyclock

2016/02/25 08:53

構いません。 そこは後でで初日を含むのか含まないのか設定で変えれるようにするつもりですので。
swordone

2016/02/25 08:58 編集

それと、2016年2月28日~4月1日の期間の扱いが、うるう年か否かで変わるというのがどうにも解せないのですが。2月28日~3月28日の期間もうるう年か否かで(1か月と1日か1か月と2日か)変わるのですか?
tkturbo

2016/02/25 12:13

もう2月は一律28日で計算していいのでは?普通なら2/28-4/28はジャスト2ヶ月でっせ
guest

回答4

0

Java8が使えるなら、PeriodとDurationを合わせて使うという方法もあります。

java

1import java.time.Duration; 2import java.time.LocalDate; 3import java.time.LocalDateTime; 4import java.time.Period; 5import java.time.format.DateTimeFormatter; 6 7public class Q28238 { 8 9 public static void main(String[] args) { 10 LocalDateTime start = LocalDateTime.parse("2014/12/25 23:45:23", DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss")); 11 LocalDateTime now = LocalDateTime.now(); 12 // 初日を1日目と数えるなら、その前の日を起点にすればいい 13 LocalDate startLd = start.toLocalDate().minusDays(1); 14 LocalDate nowLd = now.toLocalDate(); 15 Duration sec = Duration.between(start.toLocalTime(), now.toLocalTime()); 16 if(sec.isNegative()){ 17 sec = sec.plusDays(1); 18 // 繰り下がり 19 nowLd = nowLd.minusDays(1); 20 } 21 Period days = Period.between(startLd, nowLd); 22 StringBuilder builder = new StringBuilder(); 23 builder.append(days.getYears()).append("年") 24 .append(days.getMonths()).append("ヶ月") 25 .append(days.getDays()).append("日 ") 26 .append(sec.toHours()).append("時間") 27 .append(sec.toMinutes() % 60).append("分") 28 .append(sec.getSeconds() % 60).append("秒経過"); 29 System.out.println("start\t= " + start); 30 System.out.println("now\t\t= " + now); 31 System.out.println(builder); 32 } 33 34}

出力例:
start = 2014-12-20T23:45:23
now = 2016-02-25T11:31:27.787
1年2ヶ月4日 11時間46分4秒経過


Java7以下なら、Calendarクラスを最大限利用してこうなるかと…
日数については、例えば2/25->3/25の場合、2月の日数分経過していることになるので、
2/25->3/24の場合は(ゴールの年の2月の日数)-(足りない日数)になるという考えで計算しました。

java

1import static java.util.Calendar.*; 2 3import java.text.ParseException; 4import java.text.SimpleDateFormat; 5import java.util.Arrays; 6import java.util.Calendar; 7import java.util.Date; 8import java.util.Locale; 9 10public class Q28238_2 { 11 12 static int[] units = { YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, MINUTE, SECOND }; 13 14 public static void main(String[] args) throws ParseException { 15 Date start = new SimpleDateFormat("yyyy'/'MM'/'dd HH:mm:ss", Locale.JAPANESE).parse("2016/1/24 12:34:12"); 16 Date today = new SimpleDateFormat("yyyy'/'MM'/'dd HH:mm:ss", Locale.JAPANESE).parse("2016/1/25 00:10:00"); 17 int[] result = new int[units.length]; 18 19 Calendar sCal = getInstance(); 20 Calendar tCal = getInstance(); 21 22 sCal.setTime(start); 23 tCal.setTime(today); 24 25 for (int i = units.length - 1; i >= 0; i--) { 26 // 同じ単位同士で引き算 27 result[i] = tCal.get(units[i]) - sCal.get(units[i]); 28 // マイナスになった場合は繰り下がり処理 29 if (result[i] < 0) { 30 tCal.add(units[i - 1], -1); 31 int add = tCal.getActualMaximum(units[i]); 32 result[i] += (units[i] == DAY_OF_MONTH) ? add : add + 1; 33 } 34 } 35 // 何年何か月という書式にするのが面倒だったので、配列そのまま出力するコードになってます 36 System.out.println(Arrays.toString(result)); 37 } 38 39} 40

投稿2016/02/25 02:32

編集2016/02/25 08:07
swordone

総合スコア20649

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2016/02/25 06:52 編集

それぞれの日が同じで時刻期間がマイナスになると、日数期間の日部分がマイナスになってしまうので、その場合分けが必要かも… 追記:コード修正しました
guest

0

民法 第一編 第六章 期間の計算(第138条―第143条)に期間計算についての記述があります。
この条文を忠実に守るのも1つの仕様、luckyclockさんオリジナルの期間計算法を定めるのも1つの仕様です。
仕様があいまいだと、実装や検査でつらい思いをしますので、まずは仕様を固めることをお勧めします。

Excelの期間計算関数DATEDIFに深刻なバグがあることをご存じでしょうか?
このバグ回避のための、かつ民法に沿った方法がネット上にいろいろ公開されていますので、それを参考にするのも1つの手です。

投稿2016/11/27 11:53

naomi3

総合スコア1105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

日付差分だけならdifferenceDaysの中身がこんな感じでいかが?

java

1Calendar cal1 = Calendar.getInstance(); 2cal1.setTime(date1); 3Calendar cal2 = Calendar.getInstance(); 4cal2.setTime(date2); 5long longtime1 = c2.getTimeInMillis(); 6 7while(cal1.after(cal2)){ 8 longtime1 = cal1.getTimeInMillis(); 9 cal1.add(Calendar.MONTH, -1); 10} 11cal1.setTimeInMillis(longtime1); 12cal1.add(Calendar.DATE, -1 * cal2.get(Calendar.DATE); 13return (int)cal1.get(Calendar.DATE);

【追記】
年月日時分秒で差を求めるのだと下記のような感じになるかな?

java

1Calendar c1 = Calendar.getInstance(); 2c1.setTime(date1); 3 4Calendar c2 = Calendar.getInstance(); 5c2.setTime(date2); 6 7// millisecond 8c1.set(Calendar.MILLISECOND, 0); 9c2.set(Calendar.MILLISECOND, 0); 10 11// second 12int sec = c1.get(Calendar.SECOND) - c2.get(Calendar.SECOND); 13sec += (sec < 0) ? 60 : 0; 14c1.add(Calendar.SECOND, -1 * sec); 15 16// minute 17int min = c1.get(Calendar.MINUTE) - c2.get(Calendar.MINUTE); 18min += (min < 0) ? 60 : 0; 19c1.add(Calendar.MINUTE, -1 * min); 20 21// hour 22int hour = c1.get(Calendar.HOUR) - c2.get(Calendar.HOUR); 23hour += (hour < 0) ? 24 : 0; 24c1.add(Calendar.HOUR, -1 * hour); 25 26// day 27long longtime1 = c1.getTimeInMillis(); 28c1.set(Calendar.DATE, 1); 29c1.add(Calendar.DATE, -1); 30int dayInLastMonth = c1.get(Calendar.DATE); 31c1.setTimeInMillis(longtime1); 32int day = c1.get(Calendar.DATE) - c2.get(Calendar.DATE); 33day += (day < 0) ? dayInLastMonth : 0; 34c1.add(Calendar.DATE, -1 * day); 35 36// month 37int month = c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH); 38month += (month < 0) ? 12 : 0; 39c1.add(Calendar.MONTH, -1 * month); 40 41// year 42int year = c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);

投稿2016/02/25 02:38

編集2016/02/25 07:28
tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

現状では各項目をそれぞれ計算しているので正しい結果にはなりません。

下記のようにしてはいかがでしょうか。
1-現在時刻から開始時刻のミリ秒の差分をとる。
2-1の値から秒を計算する。
3-1の値から2をミリ秒に変換した値を引く
4-3の値から分を計算する。
5-3の値から4をミリ秒に変換した値を引く。
以下年までに計算する。

投稿2016/02/25 01:52

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

luckyclock

2016/02/25 02:30

6-以降どうなるのですか? 特に日を出すところまで教えてください。
yona

2016/02/25 03:13

最後まで一緒ですよ。 6-5の値から時を計算する。 7-5の値から6をミリ秒に変換した値を引く 8-7の値から日を計算する。 9-7の値から8をミリ秒に変換した値を引く。 10-9の値から月を計算する。 11-9の値から10の値をミリ秒に変換した値を引く 12-11の値から年を計算する。 13-12の値から12をミリ秒に変換した値を引く。
swordone

2016/02/25 03:19

「日を計算する」って簡単に言いますけど、月への繰り上がりが一定でないので簡単じゃないですよ。 質問者さんはそこを知りたくて質問していると思うのですが。
yona

2016/02/25 03:43

指摘ありがとうございます。その通りでした。ごめんなさい。 質問者さんは1ヶ月をどのように捉えていてどのようにしたいでしょうか。 1ヶ月は30日として捉えているのか、それとも期間内の月を考慮して1ヶ月の29日から31日まで変動するのか。 どのような仕様にする予定ですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問