teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

6

訂正

2016/02/25 08:07

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -20,7 +20,7 @@
20
20
  // 繰り下がり
21
21
  nowLd = nowLd.minusDays(1);
22
22
  }
23
- Period days = Period.between(start.toLocalDate(), nowLd);
23
+ Period days = Period.between(startLd, nowLd);
24
24
  StringBuilder builder = new StringBuilder();
25
25
  builder.append(days.getYears()).append("年")
26
26
  .append(days.getMonths()).append("ヶ月")

5

初日を1日と数えるなら、初日を1日巻き戻せばOK

2016/02/25 08:07

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -11,6 +11,8 @@
11
11
  public static void main(String[] args) {
12
12
  LocalDateTime start = LocalDateTime.parse("2014/12/25 23:45:23", DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"));
13
13
  LocalDateTime now = LocalDateTime.now();
14
+ // 初日を1日目と数えるなら、その前の日を起点にすればいい
15
+ LocalDate startLd = start.toLocalDate().minusDays(1);
14
16
  LocalDate nowLd = now.toLocalDate();
15
17
  Duration sec = Duration.between(start.toLocalTime(), now.toLocalTime());
16
18
  if(sec.isNegative()){

4

初日を1日と数えるなら,

2016/02/25 07:08

投稿

swordone
swordone

スコア20675

answer CHANGED
File without changes

3

Java8の方でも繰り下がり考慮したコードに変更

2016/02/25 07:06

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -1,6 +1,7 @@
1
1
  Java8が使えるなら、PeriodとDurationを合わせて使うという方法もあります。
2
2
  ```java
3
3
  import java.time.Duration;
4
+ import java.time.LocalDate;
4
5
  import java.time.LocalDateTime;
5
6
  import java.time.Period;
6
7
  import java.time.format.DateTimeFormatter;
@@ -8,19 +9,16 @@
8
9
  public class Q28238 {
9
10
 
10
11
  public static void main(String[] args) {
11
- //文字列を時刻に変換
12
- LocalDateTime start = LocalDateTime.parse("2014/12/20 23:45:23", DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"));
12
+ LocalDateTime start = LocalDateTime.parse("2014/12/25 23:45:23", DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"));
13
- //現在時刻を取得
14
13
  LocalDateTime now = LocalDateTime.now();
15
- //日付を元に期間(日数以上)を計算
16
- Period days = Period.between(start.toLocalDate(), now.toLocalDate());
14
+ LocalDate nowLd = now.toLocalDate();
17
- //時刻を元に期間(日数未満)を計算
18
15
  Duration sec = Duration.between(start.toLocalTime(), now.toLocalTime());
19
- //時刻ベースで現在のほうが前(startが12時に対し現在が8時など)の場合、時刻期間がマイナスになるため、日付から一日移動して調整
20
16
  if(sec.isNegative()){
21
17
  sec = sec.plusDays(1);
18
+ // 繰り下がり
22
- days = days.minusDays(1);
19
+ nowLd = nowLd.minusDays(1);
23
20
  }
21
+ Period days = Period.between(start.toLocalDate(), nowLd);
24
22
  StringBuilder builder = new StringBuilder();
25
23
  builder.append(days.getYears()).append("年")
26
24
  .append(days.getMonths()).append("ヶ月")
@@ -28,8 +26,8 @@
28
26
  .append(sec.toHours()).append("時間")
29
27
  .append(sec.toMinutes() % 60).append("分")
30
28
  .append(sec.getSeconds() % 60).append("秒経過");
31
- System.out.println("start = " + start);
29
+ System.out.println("start\t= " + start);
32
- System.out.println("now = " + now);
30
+ System.out.println("now\t\t= " + now);
33
31
  System.out.println(builder);
34
32
  }
35
33
 

2

Calendarを使う場合のコード追記

2016/02/25 06:51

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -38,4 +38,52 @@
38
38
  出力例:
39
39
  start = 2014-12-20T23:45:23
40
40
  now = 2016-02-25T11:31:27.787
41
- 1年2ヶ月4日 11時間46分4秒経過
41
+ 1年2ヶ月4日 11時間46分4秒経過
42
+
43
+ ---
44
+
45
+ Java7以下なら、Calendarクラスを最大限利用してこうなるかと…
46
+ 日数については、例えば2/25->3/25の場合、2月の日数分経過していることになるので、
47
+ 2/25->3/24の場合は(ゴールの年の2月の日数)-(足りない日数)になるという考えで計算しました。
48
+ ```java
49
+ import static java.util.Calendar.*;
50
+
51
+ import java.text.ParseException;
52
+ import java.text.SimpleDateFormat;
53
+ import java.util.Arrays;
54
+ import java.util.Calendar;
55
+ import java.util.Date;
56
+ import java.util.Locale;
57
+
58
+ public class Q28238_2 {
59
+
60
+ static int[] units = { YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, MINUTE, SECOND };
61
+
62
+ public static void main(String[] args) throws ParseException {
63
+ Date start = new SimpleDateFormat("yyyy'/'MM'/'dd HH:mm:ss", Locale.JAPANESE).parse("2016/1/24 12:34:12");
64
+ Date today = new SimpleDateFormat("yyyy'/'MM'/'dd HH:mm:ss", Locale.JAPANESE).parse("2016/1/25 00:10:00");
65
+ int[] result = new int[units.length];
66
+
67
+ Calendar sCal = getInstance();
68
+ Calendar tCal = getInstance();
69
+
70
+ sCal.setTime(start);
71
+ tCal.setTime(today);
72
+
73
+ for (int i = units.length - 1; i >= 0; i--) {
74
+ // 同じ単位同士で引き算
75
+ result[i] = tCal.get(units[i]) - sCal.get(units[i]);
76
+ // マイナスになった場合は繰り下がり処理
77
+ if (result[i] < 0) {
78
+ tCal.add(units[i - 1], -1);
79
+ int add = tCal.getActualMaximum(units[i]);
80
+ result[i] += (units[i] == DAY_OF_MONTH) ? add : add + 1;
81
+ }
82
+ }
83
+ // 何年何か月という書式にするのが面倒だったので、配列そのまま出力するコードになってます
84
+ System.out.println(Arrays.toString(result));
85
+ }
86
+
87
+ }
88
+
89
+ ```

1

余計なパッケージ宣言を削除

2016/02/25 06:48

投稿

swordone
swordone

スコア20675

answer CHANGED
@@ -1,7 +1,5 @@
1
1
  Java8が使えるなら、PeriodとDurationを合わせて使うという方法もあります。
2
2
  ```java
3
- package teratail;
4
-
5
3
  import java.time.Duration;
6
4
  import java.time.LocalDateTime;
7
5
  import java.time.Period;