Java Date Time Query








All datetime classes support queries and a query is a request for information.

We can get date time components from a datetime object, for example, we can get the year from a LocalDate.

A query requests information that is not available as components. For example, we can query a LocalDate to see if it is Monday. The result of a query can be of any type.

TemporalQuery<R> interface represents a query.

All datetime classes has a query() method with a TemporalQuery as a parameter.

TemporalQueries class contains several predefined queries.

If a datetime object does not have the information requested by the query, the query returns null.

The following code shows how to use predefined queries.

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalQueries;
import java.time.temporal.TemporalQuery;
import java.time.temporal.TemporalUnit;
//from  ww  w.j  av  a  2  s  . co  m
public class Main {

  public static void main(String[] args) {
    TemporalQuery<TemporalUnit> precisionQuery = TemporalQueries.precision();
    TemporalQuery<LocalDate> localDateQuery = TemporalQueries.localDate();

    // Query a LocalDate
    LocalDate ld = LocalDate.now();
    TemporalUnit precision = ld.query(precisionQuery);
    LocalDate queryDate = ld.query(localDateQuery);
    System.out.println("Precision of  LocalDate: " + precision);
    System.out.println("LocalDate of  LocalDate: " + queryDate);

    // Query a LocalTime
    LocalTime lt = LocalTime.now();
    precision = lt.query(precisionQuery);
    queryDate = lt.query(localDateQuery);
    System.out.println("Precision of  LocalTime: " + precision);
    System.out.println("LocalDate of  LocalTime: " + queryDate);

    // Query a ZonedDateTime
    ZonedDateTime zdt = ZonedDateTime.now();
    precision = zdt.query(precisionQuery);
    queryDate = zdt.query(localDateQuery);
    System.out.println("Precision of  ZonedDateTime:  " + precision);
    System.out.println("LocalDate of  ZonedDateTime:  " + queryDate);

  }
}

The code above generates the following result.





Custom Query

We can create a custom query in two ways.

  • implements the TemporalQuery interface
  • Use method reference as a query. The method should take a TemporalAccessor and return an object.
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalQuery;
/*  www  .  j  a va2s .c o m*/
public class Main {

  public static void main(String[] args) {
    LocalDate ld1  = LocalDate.of(2013, 12,1);
    Boolean  is = ld1.query(new Monday1Query()); 
    System.out.println(is);

  }
}

class Monday1Query implements TemporalQuery<Boolean> {
  @Override
  public Boolean queryFrom(TemporalAccessor temporal) {
    if (temporal.isSupported(ChronoField.DAY_OF_MONTH)
        && temporal.isSupported(ChronoField.DAY_OF_WEEK)) {
      int dayOfMonth = temporal.get(ChronoField.DAY_OF_MONTH);
      int weekDay = temporal.get(ChronoField.DAY_OF_WEEK);
      DayOfWeek dayOfWeek = DayOfWeek.of(weekDay);
      if (dayOfMonth == 1 && dayOfWeek == DayOfWeek.MONDAY) {
        return Boolean.TRUE;
      }
    }
    return Boolean.FALSE;
  }
}

The code above generates the following result.





Example 2

The following code rewrites the code above with method reference.

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
//  w  ww .  j  a  v a  2s  .com
public class Main {

  public static void main(String[] args) {
    LocalDate ld1  = LocalDate.of(2013, 12,   1);
    Boolean  is = ld1.query(Main::queryFrom);
    System.out.println(is);
  }
  public static Boolean queryFrom(TemporalAccessor temporal) {
    if (temporal.isSupported(ChronoField.DAY_OF_MONTH)
        && temporal.isSupported(ChronoField.DAY_OF_WEEK)) {
      int dayOfMonth = temporal.get(ChronoField.DAY_OF_MONTH);
      int weekDay = temporal.get(ChronoField.DAY_OF_WEEK);
      DayOfWeek dayOfWeek = DayOfWeek.of(weekDay);
      if (dayOfMonth == 1 && dayOfWeek == DayOfWeek.MONDAY) {
        return Boolean.TRUE;
      }
    }
    return Boolean.FALSE;
  }
}

The code above generates the following result.