content: package lambdasinaction.chap12;
  
  import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
  import static java.time.temporal.TemporalAdjusters.nextOrSame;
  
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.time.DayOfWeek;
  import java.time.Duration;
  import java.time.Instant;
  import java.time.LocalDate;
  import java.time.LocalDateTime;
  import java.time.LocalTime;
  import java.time.Month;
  import java.time.chrono.JapaneseDate;
  import java.time.format.DateTimeFormatter;
  import java.time.format.DateTimeFormatterBuilder;
  import java.time.temporal.ChronoField;
  import java.time.temporal.ChronoUnit;
  import java.time.temporal.Temporal;
  import java.time.temporal.TemporalAdjuster;
  import java.util.Calendar;
  import java.util.Date;
  import java.util.Locale;
  
  public class DateTimeExamples {
  
      private static final ThreadLocal<DateFormat> formatters = new ThreadLocal<DateFormat>() {
          protected DateFormat initialValue() {
              return new SimpleDateFormat("dd-MMM-yyyy");
          }
      };
  
      public static void main(String[] args) {
          useOldDate();
          useLocalDate();
          useTemporalAdjuster();
          useDateFormatter();
      }
  
      private static void useOldDate() {
          Date date = new Date(114, 2, 18);
          System.out.println(date);
  
          System.out.println(formatters.get().format(date));
  
          Calendar calendar = Calendar.getInstance();
          calendar.set(2014, Calendar.FEBRUARY, 18);
          System.out.println(calendar);
      }
  
      private static void useLocalDate() {
          LocalDate date = LocalDate.of(2014, 3, 18);
          int year = date.getYear(); // 2014
          Month month = date.getMonth(); // MARCH
          int day = date.getDayOfMonth(); // 18
          DayOfWeek dow = date.getDayOfWeek(); // TUESDAY
          int len = date.lengthOfMonth(); // 31 (days in March)
          boolean leap = date.isLeapYear(); // false (not a leap year)
          System.out.println(date);
  
          int y = date.get(ChronoField.YEAR);
          int m = date.get(ChronoField.MONTH_OF_YEAR);
          int d = date.get(ChronoField.DAY_OF_MONTH);
  
          LocalTime time = LocalTime.of(13, 45, 20); // 13:45:20
          int hour = time.getHour(); // 13
          int minute = time.getMinute(); // 45
          int second = time.getSecond(); // 20
          System.out.println(time);
  
          LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20); // 2014-03-18T13:45
          LocalDateTime dt2 = LocalDateTime.of(date, time);
          LocalDateTime dt3 = date.atTime(13, 45, 20);
          LocalDateTime dt4 = date.atTime(time);
          LocalDateTime dt5 = time.atDate(date);
          System.out.println(dt1);
  
          LocalDate date1 = dt1.toLocalDate();
          System.out.println(date1);
          LocalTime time1 = dt1.toLocalTime();
          System.out.println(time1);
  
          Instant instant = Instant.ofEpochSecond(44 * 365 * 86400);
          Instant now = Instant.now();
  
          Duration d1 = Duration.between(LocalTime.of(13, 45, 10), time);
          Duration d2 = Duration.between(instant, now);
          System.out.println(d1.getSeconds());
          System.out.println(d2.getSeconds());
  
          Duration threeMinutes = Duration.of(3, ChronoUnit.MINUTES);
          System.out.println(threeMinutes);
  
          JapaneseDate japaneseDate = JapaneseDate.from(date);
          System.out.println(japaneseDate);
      }
  
      private static void useTemporalAdjuster() {
          LocalDate date = LocalDate.of(2014, 3, 18);
          date = date.with(nextOrSame(DayOfWeek.SUNDAY));
          System.out.println(date);
          date = date.with(lastDayOfMonth());
          System.out.println(date);
  
          date = date.with(new NextWorkingDay());
          System.out.println(date);
          date = date.with(nextOrSame(DayOfWeek.FRIDAY));
          System.out.println(date);
          date = date.with(new NextWorkingDay());
          System.out.println(date);
  
          date = date.with(nextOrSame(DayOfWeek.FRIDAY));
          System.out.println(date);
          date = date.with(temporal -> {
              DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
              int dayToAdd = 1;
              if (dow == DayOfWeek.FRIDAY) dayToAdd = 3;
              if (dow == DayOfWeek.SATURDAY) dayToAdd = 2;
              return temporal.plus(dayToAdd, ChronoUnit.DAYS);
          });
          System.out.println(date);
      }
  
      private static class NextWorkingDay implements TemporalAdjuster {
          @Override
          public Temporal adjustInto(Temporal temporal) {
              DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
              int dayToAdd = 1;
              if (dow == DayOfWeek.FRIDAY) dayToAdd = 3;
              if (dow == DayOfWeek.SATURDAY) dayToAdd = 2;
              return temporal.plus(dayToAdd, ChronoUnit.DAYS);
          }
      }
  
      private static void useDateFormatter() {
          LocalDate date = LocalDate.of(2014, 3, 18);
          DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
          DateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.ITALIAN);
  
          System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE));
          System.out.println(date.format(formatter));
          System.out.println(date.format(italianFormatter));
  
          DateTimeFormatter complexFormatter = new DateTimeFormatterBuilder()
                  .appendText(ChronoField.DAY_OF_MONTH)
                  .appendLiteral(". ")
                  .appendText(ChronoField.MONTH_OF_YEAR)
                  .appendLiteral(" ")
                  .appendText(ChronoField.YEAR)
                  .parseCaseInsensitive()
                  .toFormatter(Locale.ITALIAN);
  
          System.out.println(date.format(complexFormatter));
      }
  
  }
  