回答編集履歴

6

訂正

2016/02/25 08:07

投稿

swordone
swordone

スコア20649

test CHANGED
@@ -42,7 +42,7 @@
42
42
 
43
43
  }
44
44
 
45
- Period days = Period.between(start.toLocalDate(), nowLd);
45
+ Period days = Period.between(startLd, nowLd);
46
46
 
47
47
  StringBuilder builder = new StringBuilder();
48
48
 

5

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

2016/02/25 08:07

投稿

swordone
swordone

スコア20649

test CHANGED
@@ -23,6 +23,10 @@
23
23
  LocalDateTime start = LocalDateTime.parse("2014/12/25 23:45:23", DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"));
24
24
 
25
25
  LocalDateTime now = LocalDateTime.now();
26
+
27
+ // 初日を1日目と数えるなら、その前の日を起点にすればいい
28
+
29
+ LocalDate startLd = start.toLocalDate().minusDays(1);
26
30
 
27
31
  LocalDate nowLd = now.toLocalDate();
28
32
 

4

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

2016/02/25 07:08

投稿

swordone
swordone

スコア20649

test CHANGED
File without changes

3

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

2016/02/25 07:06

投稿

swordone
swordone

スコア20649

test CHANGED
@@ -3,6 +3,8 @@
3
3
  ```java
4
4
 
5
5
  import java.time.Duration;
6
+
7
+ import java.time.LocalDate;
6
8
 
7
9
  import java.time.LocalDateTime;
8
10
 
@@ -18,31 +20,25 @@
18
20
 
19
21
  public static void main(String[] args) {
20
22
 
21
- //文字列を時刻に変換
22
-
23
- LocalDateTime start = LocalDateTime.parse("2014/12/20 23:45:23", DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"));
23
+ LocalDateTime start = LocalDateTime.parse("2014/12/25 23:45:23", DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"));
24
-
25
- //現在時刻を取得
26
24
 
27
25
  LocalDateTime now = LocalDateTime.now();
28
26
 
29
- //日付を元に期間(日数以上)を計算
30
-
31
- Period days = Period.between(start.toLocalDate(), now.toLocalDate());
27
+ LocalDate nowLd = now.toLocalDate();
32
-
33
- //時刻を元に期間(日数未満)を計算
34
28
 
35
29
  Duration sec = Duration.between(start.toLocalTime(), now.toLocalTime());
36
-
37
- //時刻ベースで現在のほうが前(startが12時に対し現在が8時など)の場合、時刻期間がマイナスになるため、日付から一日移動して調整
38
30
 
39
31
  if(sec.isNegative()){
40
32
 
41
33
  sec = sec.plusDays(1);
42
34
 
35
+ // 繰り下がり
36
+
43
- days = days.minusDays(1);
37
+ nowLd = nowLd.minusDays(1);
44
38
 
45
39
  }
40
+
41
+ Period days = Period.between(start.toLocalDate(), nowLd);
46
42
 
47
43
  StringBuilder builder = new StringBuilder();
48
44
 
@@ -58,9 +54,9 @@
58
54
 
59
55
  .append(sec.getSeconds() % 60).append("秒経過");
60
56
 
61
- System.out.println("start = " + start);
57
+ System.out.println("start\t= " + start);
62
58
 
63
- System.out.println("now = " + now);
59
+ System.out.println("now\t\t= " + now);
64
60
 
65
61
  System.out.println(builder);
66
62
 

2

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

2016/02/25 06:51

投稿

swordone
swordone

スコア20649

test CHANGED
@@ -79,3 +79,99 @@
79
79
  now = 2016-02-25T11:31:27.787
80
80
 
81
81
  1年2ヶ月4日 11時間46分4秒経過
82
+
83
+
84
+
85
+ ---
86
+
87
+
88
+
89
+ Java7以下なら、Calendarクラスを最大限利用してこうなるかと…
90
+
91
+ 日数については、例えば2/25->3/25の場合、2月の日数分経過していることになるので、
92
+
93
+ 2/25->3/24の場合は(ゴールの年の2月の日数)-(足りない日数)になるという考えで計算しました。
94
+
95
+ ```java
96
+
97
+ import static java.util.Calendar.*;
98
+
99
+
100
+
101
+ import java.text.ParseException;
102
+
103
+ import java.text.SimpleDateFormat;
104
+
105
+ import java.util.Arrays;
106
+
107
+ import java.util.Calendar;
108
+
109
+ import java.util.Date;
110
+
111
+ import java.util.Locale;
112
+
113
+
114
+
115
+ public class Q28238_2 {
116
+
117
+
118
+
119
+ static int[] units = { YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, MINUTE, SECOND };
120
+
121
+
122
+
123
+ public static void main(String[] args) throws ParseException {
124
+
125
+ Date start = new SimpleDateFormat("yyyy'/'MM'/'dd HH:mm:ss", Locale.JAPANESE).parse("2016/1/24 12:34:12");
126
+
127
+ Date today = new SimpleDateFormat("yyyy'/'MM'/'dd HH:mm:ss", Locale.JAPANESE).parse("2016/1/25 00:10:00");
128
+
129
+ int[] result = new int[units.length];
130
+
131
+
132
+
133
+ Calendar sCal = getInstance();
134
+
135
+ Calendar tCal = getInstance();
136
+
137
+
138
+
139
+ sCal.setTime(start);
140
+
141
+ tCal.setTime(today);
142
+
143
+
144
+
145
+ for (int i = units.length - 1; i >= 0; i--) {
146
+
147
+ // 同じ単位同士で引き算
148
+
149
+ result[i] = tCal.get(units[i]) - sCal.get(units[i]);
150
+
151
+ // マイナスになった場合は繰り下がり処理
152
+
153
+ if (result[i] < 0) {
154
+
155
+ tCal.add(units[i - 1], -1);
156
+
157
+ int add = tCal.getActualMaximum(units[i]);
158
+
159
+ result[i] += (units[i] == DAY_OF_MONTH) ? add : add + 1;
160
+
161
+ }
162
+
163
+ }
164
+
165
+ // 何年何か月という書式にするのが面倒だったので、配列そのまま出力するコードになってます
166
+
167
+ System.out.println(Arrays.toString(result));
168
+
169
+ }
170
+
171
+
172
+
173
+ }
174
+
175
+
176
+
177
+ ```

1

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

2016/02/25 06:48

投稿

swordone
swordone

スコア20649

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