ゆるふわ技術日誌

ゆるくふわっと広く浅く。

SimpleDateFormatのparseでコケるときに確認すること #60

今日やったこと

SimpleDateFormatのparse

今日は講義で作らされている作っているAndroidアプリ開発について。(というよりJavaのオハナシです。)

JavaThu, 13 Jul 2017 18:00:15 +0900 こういう形式の文字列をDate型に変換したいとき、ありませんか?

こんな感じで

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
        System.out.println(sdf.parse("Thu, 13 Jul 2017 18:00:15 +0900"));
    }
}

SimpleDateFormatのparseメソッドを使うと実現できる…といろんな記事に書いているのですが、実際に実行すると

Exception in thread "main" java.text.ParseException: Unparseable date: "Thu, 13 Jul 2017 18:00:15 +0900"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at Main.main(Main.java:15)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Unparseableですって奥さん…。

おかしいなーと数時間も頭を悩ませてしまいましたが、正解はこうでした。

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
        System.out.println(sdf.parse("Thu, 13 Jul 2017 18:00:15 +0900"));
    }
}

3行目、SimpleDateFormatのコンストラクタの第二引数にLocaleを渡しています。

これでちゃんと Thu Jul 13 18:00:15 JST 2017 という出力が得られます。ヤッタネ。

どういうことなの

勘のいい方はどういうことかすでにお分かりかと思いますが、なんでLocaleを指定すると動いたかというと、先程のLocaleの指定なしsdfでformatしてみると 木, 13 7 2017 22:08:43 +0900 という出力が返ってきます。

…。これが犯人でした。

パターン文字列 EEEってLocaleによって出力が変わっちゃうんですね。環境依存にならないためにもLocaleの指定はした方が良さそうですね。


なんとなくQiitaにも投げました。内容同じです。

qiita.com

雑談

この講義のためだけに週1回だけJava書いてるわけですが、やっぱりこういうかっちりした言語はそれはそれでたのしいです。


研究室、自己推薦通りました👍