昔上司が作った、csvから時刻を抜き出してごにょごにょする、みたいな簡易プログラムがあるのだが、
それをSimpleDateFormat→LocalDateTimeに改修することになった。
とはいっても、使い方はほとんど同じで、
- DateTimeFormatterで日付形式を定義する
- Stringで時刻を取り出してLocalDateTimeに変換する
- ごにょごにょする
何ら変わらん。と思って、意気揚々とコードを組むわたし。
DateTimeFormatter csvFormat = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
String filename = "hoge.csv";
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "SJIS"));
try {
//CSVを読み込む
while ((line = br.readLine()) != null) {
//切り出す
String[] csvarr = line.split(",");
String time1 = csvarr[0];
String time2 = csvarr[1];
try {
//LocalDateTimeに変換する
LocalDateTime ldt1 = LocalDateTime.parse(time1, csvFormat);
LocalDateTime ldt2 = LocalDateTime.parse(time2, csvFormat);
//ごにょごにょする(略)
} catch(DateTimeParseException ex) {
ex.printStackTrace();
}
} catch(IOException ex) {
ex.printStackTrace();
}
} catch (UnsupportedEncodingException | FileNotFoundException ex) {
ex.printStackTrace();
}
try~catchばっかりで見苦しいわ、という感じで申し訳ないのですが、
要はCSVから取ってきてLocalDateTimeに変換しているだけです。
ところが。
java.time.format.DateTimeParseException: Text '2016/08/02 4:30:23' could not be parsed at index 11
at java.time.format.DateTimeFormatter.parseResolved0
at java.time.format.DateTimeFormatter.parse
at java.time.LocalDateTime.parse
フォーマッタに突っ込むところでコケた。
いやいや、SimpleDateTimeはこれでうまくいってたのに、どういうことと思って調べてみたら、
どうやらLocalDateTime(というかDateTimeFormatter)はフォーマットの形式判定が厳格になっているらしく、今回のようにHHと定義すると、時間が2桁でないとダメということのようです。だからcould not be persed at index 11なのね・・・
DateTimeFormatter csvFormat = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
String time1 = "2016/08/02 4:30:23" //×
String time2 = "2016/08/02 04:30:23" //○
一桁は0埋めしないとダメみたいです。
しかし、じゃあH:mm:ss
としてあげればいいのかというと、そうすると12時とか午後の時間とかは問答無用でアウトになってしまう。
1桁2桁どちらでも対応できるようには、以下のようにしてあげればいい。基本1桁だけど、2桁来るときもあるよ、みたいな感じですかね。
DateTimeFormatter csvFormat = DateTimeFormatter.ofPattern("yyyy/MM/dd []H:mm:ss");
String time1 = "2016/08/02 4:30:23" //○
String time2 = "2016/08/02 04:30:23" //○
勿論、時だけではなく、分や秒でも使えます。