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

回答編集履歴

3

2つ目の方法のコード例を追加

2020/04/22 09:05

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -76,4 +76,42 @@
76
76
  unmatch format.
77
77
  null
78
78
  === OK ===
79
+ ```
80
+
81
+ #追加2
82
+ 1つ目,2つ目,3つ目...と試す形の場合, 3パターン程度であればあるいは直接並べても良いかもしれませんが, 例えば配列とループにして成功するまで回すという形に出来ます.
83
+ ```java
84
+ private static DateTimeFormatter parsers[] = new DateTimeFormatter[] {
85
+ DateTimeFormatter.ofPattern("yyyy/MM/dd"),
86
+ DateTimeFormatter.ofPattern("yyyy-MM-dd"),
87
+ DateTimeFormatter.ofPattern("yyyyMMdd")
88
+ };
89
+ private static LocalDate parse(String str) throws DateTimeParseException {
90
+ DateTimeParseException ex = null;
91
+ for(DateTimeFormatter parser : parsers) {
92
+ try {
93
+ return LocalDate.parse(str, parser);
94
+ } catch(DateTimeParseException e) {
95
+ ex = e;
96
+ }
97
+ }
98
+ throw ex;
99
+ }
100
+ ```
101
+ ```plain text
102
+ 4567-12-03
103
+ 4567-12-03
104
+ 4567-12-03
105
+ Text '4567123' could not be parsed at index 6
106
+ Text '456712301' could not be parsed at index 0
107
+ Text '4567-12/30' could not be parsed at index 4
108
+ Text '4567=12=30' could not be parsed at index 4
109
+ Text '4567-12-00' could not be parsed at index 4
110
+ Text '4567-00-30' could not be parsed at index 4
111
+ Text '456-12-30' could not be parsed at index 0
112
+ Text '45678-12-30' could not be parsed at index 4
113
+ Text '' could not be parsed at index 0
114
+ Text 'A-B-C' could not be parsed at index 0
115
+ text
116
+ === OK ===
79
117
  ```

2

追加

2020/04/22 09:05

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -5,7 +5,7 @@
5
5
  もう1つは, 1つ目で変換できなかったら2つ目の変換, 2つ目の変換で変換できなかったら3つ目の変換...と変換できるまで(もしくは変換するフォーマットが無くなるまで)変換を試すことです.
6
6
 
7
7
  #追加
8
- 正規表現で解析するなら, このような感じでしょうか.
8
+ 3つ目(?)として正規表現で解析するなら, このような感じでしょうか.
9
9
  ```java
10
10
  import java.util.*;
11
11
  import java.util.regex.*;
@@ -59,4 +59,21 @@
59
59
  }
60
60
  }
61
61
  }
62
+ ```
63
+ ```plain text
64
+ 4567-12-03
65
+ 4567-12-03
66
+ 4567-12-03
67
+ unmatch format.
68
+ unmatch format.
69
+ unmatch format.
70
+ unmatch format.
71
+ unmatch format.
72
+ unmatch format.
73
+ unmatch format.
74
+ unmatch format.
75
+ unmatch format.
76
+ unmatch format.
77
+ null
78
+ === OK ===
62
79
  ```

1

追加

2020/04/22 06:56

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -2,4 +2,61 @@
2
2
 
3
3
  1つは, 先に文字列を加工して一定の形式に変換してから年月日として解析することです. (y_waiwai さんが回答されている方法です)
4
4
 
5
- もう1つは, 1つ目で変換できなかったら2つ目の変換, 2つ目の変換で変換できなかったら3つ目の変換...と変換できるまで(もしくは変換するフォーマットが無くなるまで)変換を試すことです.
5
+ もう1つは, 1つ目で変換できなかったら2つ目の変換, 2つ目の変換で変換できなかったら3つ目の変換...と変換できるまで(もしくは変換するフォーマットが無くなるまで)変換を試すことです.
6
+
7
+ #追加
8
+ 正規表現で解析するなら, このような感じでしょうか.
9
+ ```java
10
+ import java.util.*;
11
+ import java.util.regex.*;
12
+ import java.time.*;
13
+ import java.time.format.*;
14
+
15
+ public class Main {
16
+ private static class TestCase {
17
+ final String str;
18
+ final boolean result;
19
+ private TestCase(String str, boolean result) { this.str = str; this.result = result; }
20
+ static TestCase True(String str) { return new TestCase(str, true); }
21
+ static TestCase False(String str) { return new TestCase(str, false); }
22
+ }
23
+ public static void main(String[] args) throws Exception {
24
+ TestCase testPattern[] = {
25
+ TestCase.True("45671203"),TestCase.True("4567/12/03"),TestCase.True("4567-12-03"),
26
+
27
+ TestCase.False("4567123"),TestCase.False("456712301"),
28
+ TestCase.False("4567-12/30"),TestCase.False("4567=12=30"),TestCase.False("4567-12-00"),
29
+ TestCase.False("4567-00-30"),TestCase.False("456-12-30"),TestCase.False("45678-12-30"),
30
+ TestCase.False(""),TestCase.False("A-B-C"),TestCase.False(null),
31
+ };
32
+ String totalResult = "=== OK ===";
33
+ for(TestCase test : testPattern) {
34
+ if(testParse(test.str) != test.result) totalResult = "*** ERR ***";
35
+ }
36
+ System.out.println(totalResult);
37
+ }
38
+ private static boolean testParse(String str) {
39
+ try {
40
+ LocalDate a = parse(str);
41
+ System.out.println(a);
42
+ return true;
43
+ } catch(Exception e) {
44
+ System.out.println(e.getMessage());
45
+ return false;
46
+ }
47
+ }
48
+ private static Pattern DateParsePattern = Pattern.compile("(\d{4})([/-]?)(\d{2})\2(\d{2})");
49
+ private static LocalDate parse(String str) throws DateTimeParseException {
50
+ Matcher m = DateParsePattern.matcher(str);
51
+ if(!m.matches()) throw new DateTimeParseException("unmatch format.", str, -1);
52
+ try {
53
+ int year = Integer.parseInt(m.group(1));
54
+ Month month = Month.of(Integer.parseInt(m.group(3)));
55
+ int dayOfMonth = Integer.parseInt(m.group(4));
56
+ return LocalDate.of(year, month, dayOfMonth);
57
+ } catch(DateTimeException e) {
58
+ throw new DateTimeParseException("unmatch format.", str, -1, e);
59
+ }
60
+ }
61
+ }
62
+ ```