SimpleDateFormat もこれもうわかんねぇな


結果

1.8

H

11

平成

環境

1.8

java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

11

openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

コード

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Date;
import java.util.Locale;

public class Main {

    public static void main(final String[] args) {
        final Date date = date(2010, 3, 4);
        final SimpleDateFormat format = new SimpleDateFormat("G", new Locale("ja", "JP", "JP"));
        System.out.println(format.format(date));
    }

    private static Date date(final int year, final int month, final int dayOfMonth) {
        final long time = LocalDate.of(year, month, dayOfMonth)
            .atStartOfDay(ZoneOffset.ofHours(9)).toEpochSecond() * 1000;
        return new Date(time);
    }
}

関連(しない)

関連(する)

From JDK 9 onwards, the default locale data is the data derived from the Unicode Consortium’s Common Locale Data Repository (CLDR). Please refer https://www.unicode.org/cldr/charts/33/by_type/date_&_time.japanese.html
The short display format for Heisei is 平成 in the ja locale in CLDR data. Hence the difference in the result.

Read more ⟶

%s に null を渡したらどうなるんだっけ


こたえ

文字列 null が出力される。

コード

    final String text = null;
    System.out.printf("%s", text);

参考

For category General, Character, Numberic, Integral and Date/Time conversion, unless otherwise specified, if the argument arg is null, then the result is “null”.

リンク先の表にある通り、 s はカテゴリ"general"に属す。ちなみに日本語ではこうなっている(わかりにくい):

Read more ⟶

DateTimeFormatter とかこれもうわかんねぇな


コード

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class App {

    private static String format(final LocalDate date, final String pattern) {
        return date.format(DateTimeFormatter.ofPattern(pattern, Locale.JAPAN));
    }

    public static void main(final String[] args) {
        final LocalDate today = LocalDate.of(2019, 6, 4);

        System.out.println(format(today, "M"));
        System.out.println(format(today, "MM"));
        System.out.println(format(today, "MMM"));
        System.out.println(format(today, "MMMM"));
        System.out.println(format(today, "MMMMM"));
        System.out.println(format(today, "MMMMMM"));
    }
}

結果

パターン 結果
M 6
MM 06
MMM 6 月
MMMM 6 月
MMMMM 6
MMMMMM IllegalArgumentException: Too many pattern letters: M
$ java -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

参考(にならなかった)リンク

参考(にややなった)リンク

関連(しない)

Read more ⟶

Spring Bootで コンポーネント外からコンポーネントを取得したかった


動機

CDI で言うところの CDI.current().getBeans(...) とか CDI.current().select(...)とかそんな感じのことをやりたかった。

参考リファレンス

ドキュメントでは、やりたいことが書いてあるように見えたのはこのセクション

Read more ⟶

Spring Boot 2.1 でテスト時 @Bean を挿げ替えたかった


動機

ユニットテスト実行時に java.time.Clock を特定の時間に固定して再現性のあるテスト(現在の時刻に依存しないテスト)を作成したかった。

考え方/方針

@Configuration@Bean を定義して Clock をインジェクションできるようにし、実装ではそれを用いる。

Read more ⟶

text/plain で JSON を投げつけてくるヤツに対処する


の別解。

@Autowired
private RestTemplateBuilder builder;

...
    final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN));
    final RestTemplate restTemplate = builder.additionalMessageConverters(converter).build();

ちなみに上記のようにコンバータを明示的に設定しない場合だと次のような例外になる :

Read more ⟶

Java9以降.propertiesファイルをUTF-8で書けるようになった、は正しい?


解答

正しくない。

  • Java9(JEP226)で変わったのはリソースバンドルの取り扱い(PropertyResourceBundle) であって プロパティファイル .properties 全般の話ではない。
  • プロパティファイル.propertiesの文字エンコーディングについての取り決めはない。それを取り扱うプログラム次第でありUTF-8を正しく認識してくれるとは限らない。
    • 標準 API で UTF-8として(読もうと思えば)読めるようになったのは 1.6 からであって 9 からではない。ちなみに 1.5 以前は ISO 8859-1 前提。

背景

私はうろ覚えで何となく、現在の Java では .properties ファイルを UTF-8 で書ける、ascii2nativeは過去の遺物になった、のだと思いこんでいました。
ところが Spring Boot の application.propertiesUTF-8 で日本語を書いたところ文字化けしてしまい、あれ、もしかして自分の理解が間違っているのかと思い調べ直したのがこの記事です。

Read more ⟶

Testing the Web Layer のコードを JUnit Jupiter にマイグレーションしてみる


概要

(追記: ここで試したのは2.1.4.RELEASE時点のもの。2.2.0.M3以降では #14736の通り JUnit5 がデフォルトになっている模様。)

spring-boot-starter-test の JUnit5 対応はこちらの issue:

Read more ⟶

Spring Validator(でラップされたBean Validation)のメッセージをi18nしたときの覚え書き


やりたかったこと

  • BeanValidation のプロパティファイル ValidationMessages.properties でなく、 Spring のメッセージプロパティに統合したい。
    • Spring のメッセージプロパティとは?
  • Accept-Languageベースでメッセージを国際化したい。

調べた

Spring のメッセージプロパティファイルはどこ?

これはキーワード “site:spring.io i18n message” でググるとすぐ見つかった。

Read more ⟶

RPGツクールMVをバージョン管理するための初期設定


他の方が同じ話題で次のエントリを書かれていましたが、gulp 何それ状態なので理解できませんでした。理解できる方はそちらの方が良いのかもしれません。

Read more ⟶

Hibernate で CHAR を String にマップする


例えば、生 JDBC でchar型カラムのクエリを書くとString型にマップされます

    final Connection connection = DriverManager.getConnection(...);
    final Statement statement = connection.createStatement();
    final ResultSet resultSet = statement.executeQuery("select char_column from foo_table");

    // java.lang.String
    resultSet.getMetaData().getColumnClassName(1);

が、Hibernate の Native query を用いて同じように実行するとCharacter型にマップされます:

Read more ⟶

Eclipseの起動に使用するJDKを指定する(Mac)


最新の JDK をインストールしたが、古いバージョンの Eclipse も利用したい(が最新のバージョンでは起動できない)ような場合に必要となる設定です。

設定するファイルと設定方法

Eclipse.app/Contents/Eclipse にある eclipse.ini に、所望のバージョンの java コマンドが入っているディレクトリを指定します。
/usr/libexec/java_home -VJAVA_HOME 候補一覧が参照できますので、このディレクトリ + /bin を指定することになります。

Read more ⟶

Ubuntu18.04 端末の不快なエラー音 消す方法


Ubuntu を 18.04 にアップグレードしたら端末の補完処理で tab キーを押す度にヴヴッという不快なビープ音が鳴るようになってしまった。

端末のメニューから 設定 を選択し設定ダイアログを開く。
ダイアログで自分の使用しているプロファイル(ここではデフォルト)を選択し、文字タブのSoundオプションで端末ベルを鳴らすのチェックを外せば OK。

Read more ⟶