/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.timeseries.date.localdate; import org.threeten.bp.LocalDate; /** * An encoder between {@code LocalDate} and {@code int}. * <p> * The {@linkplain LocalDate#MAX maximum date} is converted to {@code Integer.MAX_VALUE}. * The {@linkplain LocalDate#MIN minimum date} is converted to {@code Integer.MIN_VALUE}. * Other values are encoded by multiplying the year by 10,000 and the month by 100. * Thus the date 2012-06-30 will be converted to the number 20,120,630. * Any date with a year outside the range 0000 to 9999 throws an exception. */ public final class LocalDateToIntConverter { /** * Restricted constructor. */ private LocalDateToIntConverter() { } //------------------------------------------------------------------------- /** * Converts a {@code LocalDate} to an {@code int}. * <p> * See the class Javadoc for the format of the {@code int}. * * @param date the date to convert, not null * @return the {@code int} equivalent * @throws IllegalArgumentException if the date is too large */ public static int convertToInt(LocalDate date) { int year = date.getYear(); int month = date.getMonthValue(); int day = date.getDayOfMonth(); if (year > 9999) { if (date.equals(LocalDate.MAX)) { return Integer.MAX_VALUE; } throw new IllegalArgumentException("LocalDate has year > 9999"); } if (year < 0) { if (date.equals(LocalDate.MIN)) { return Integer.MIN_VALUE; } throw new IllegalArgumentException("LocalDate has year < 0"); } return year * 10000 + month * 100 + day; } /** * Converts an {@code int} to an {@code LocalDate}. * <p> * See the class Javadoc for the format of the {@code int}. * * @param date the {@code int} date to convert * @return the {@code LocalDate} equivalent, not null */ public static LocalDate convertToLocalDate(int date) { if (date == Integer.MAX_VALUE) { return LocalDate.MAX; } if (date == Integer.MIN_VALUE) { return LocalDate.MIN; } int year = date / 10000; int month = (date / 100) % 100; int day = date % 100; return LocalDate.of(year, month, day); } /** * Checks an {@code int} date is valid. * <p> * See the class Javadoc for the format of the {@code int}. * * @param date the {@code int} date to check * @throws IllegalArgumentException if the date is invalid */ public static void checkValid(int date) { int year = date / 10000; int month = (date / 100) % 100; int day = date % 100; if (year < 0 && date != Integer.MIN_VALUE) { throw new IllegalArgumentException("Date must be year zero or later"); } if (year > 9999 && date != Integer.MAX_VALUE) { throw new IllegalArgumentException("Date must be year 9999 or earlier"); } if (month < 1 || month > 12 || day < 1 || day > 31) { throw new IllegalArgumentException("Invalid month-day"); } if (day > 29 && VALID_MONTH_DAY[(month - 1) * 2 + (day - 30)] == false) { throw new IllegalArgumentException("Invalid month-day"); } } private static final boolean[] VALID_MONTH_DAY = { true, true, // Jan false, false, // Feb true, true, // Mar true, false, // Apr true, true, // May true, false, // Jun true, true, // Jul true, true, // Aug true, false, // Sep true, true, // Oct true, false, // Nov true, true, // Dec }; }