LoginSignup
0
1

More than 5 years have passed since last update.

[Java1.8] java.timeを使ってBetweenを作ってみる

Last updated at Posted at 2015-09-16

IntStream.range(int from,int to)のようなものがDateでもほしいなあと思い、作ってみました。

実装

Between.java
@ValidTrue("from < to")
public class Between<T extends Temporal & Comparable<? super T>> {
    private T from;
    private T to;

    public Between(T from, T to){
        this.from = from;
        this.to = to;
    }
    public Stream<T> each(ChronoUnit unit, UnaryOperator<T> adjuster, int skip){
        T adjfrom = adjuster.apply(from);
        while(from.compareTo(adjfrom)>0) adjfrom = unit.addTo(from, 1);

        long size = adjfrom.until(to, unit)/skip;

        return Stream.iterate(adjfrom, d -> unit.addTo(d, skip)).limit(size);
    }
}

TemporalAdjusterというのが、Temporal -> Temporalの修正変換をしてくれるのですが、これ TemporalAdjuster<T extends Temporal>じゃないんです・・・adjustすると型を失ってしまうので使えないという・・・・T型を復活する方法がありませんかね。
TemporalQueryを自分で作るのだろうか。

Test

BetweenTest.java
public class BetweenTest {
    @Test
    public void test(){
        //毎日
        Between<LocalDate> between = new Between<>(LocalDate.now(),LocalDate.now().plusDays(50));
        between.each(ChronoUnit.DAYS , d -> d ,1).forEach(System.out::println);
        System.out.println("***********");

        //隔週日曜日
        between.each(ChronoUnit.WEEKS , d -> d.with(DayOfWeek.SUNDAY) ,2).forEach(System.out::println);
        System.out.println("***********");

        //毎月最終日
        Between<YearMonth> between2 = new Between<>(YearMonth.now(),YearMonth.now().plusMonths(12));
        between2.each(ChronoUnit.MONTHS , m -> m , 1  ).map( YearMonth::atEndOfMonth ).forEach(System.out::println);
        System.out.println("***********");

        //毎月第3日曜日
        between2.each(ChronoUnit.MONTHS , m -> m , 1  ).map( d -> d.atDay(1).with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.SUNDAY ))).forEach(System.out::println);
        System.out.println("***********");

        //毎年4月1日
        Between<Year> between3 = new Between<>(Year.now(),Year.now().plusYears(10));
        between3.each(ChronoUnit.YEARS, y -> y, 1).map( y -> y.atMonthDay(MonthDay.of(4, 1))).forEach(System.out::println);
    }
}

というわけで、いろんなTemporalのリストが作れそうです。

総括

考え中・・・

課題

  • TemporalAdjuster・・・
  • Day型がない
  • T型を復活する方法
  • y -> y これを書くクールなラムダ式を教えてください。

(追加)

        //毎週土曜日と日曜日
        between.each(ChronoUnit.WEEKS , d -> d.with(DayOfWeek.SATURDAY) ,1).flatMap( d -> Stream.of(d,d.plusDays(1))).forEach(System.out::println);

まあ、

between.stream().filter( d -> d.getDayOfWeek()==DayOfWeek.SUNDAY ||d.getDayOfWeek()==DayOfWeek.SATURDAY)

みたいに全部フィルタでいいよと言われるとまあそれでもいいんですが、全日走査するより早いじゃん、と言う気分です。

0
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1