読者です 読者をやめる 読者になる 読者になる

Java で横長カレンダーを書くための処理

先日、jQuery で横長の帯状のカレンダーを書くための処理を書いて
横長カレンダーを書く - Oboe吹きプログラマの黙示録
、では Java だったらどう書く?
と思ったので書いてみました。

例えば、

LocalDate start = LocalDate.parse("2016-12-22");
LocalDate end   = LocalDate.parse("2017-01-05");

という開始日付と終了日付が与えられてる場合です。

まず、日(day) を並べてみます。無限 Stream 生成して開始と終了の差で制限を書けて Stream を完結させます。

Stream.iterate(start, d->d.plusDays(1)).limit(Period.between(start, end).getDays() + 1).forEach(e->{
  System.out.print(e.getDayOfMonth() + " ");
});

以下のようになります。

22 23 24 25 26 27 28 29 30 31 1 2 3 4 5 

問題は月で、この場合の月として割り当てた時の日数の長さを求めたいのです。
無理やり、Stream の 実行を繋げて処理を書くと。。。

Stream.iterate(start, d->d.plusDays(1)).limit(Period.between(start, end).getDays() + 1)
.map(e->LocalDate.of(e.getYear(), e.getMonthValue(), 1)).collect(Collectors.groupingBy(e->e, Collectors.counting()))
.entrySet().stream().sorted((e1, e2)->e1.getKey().compareTo(e2.getKey())).forEach(e->{
   System.out.println( e.getKey().getMonthValue() + "月 : " + e.getValue() + " days");
});

長いけど、Cool に見えてきます。

12月 : 10 days
1月 : 5 days

となり、12月→1月の順番を保てます。