/** * Copyright 2011-2017 Asakusa Framework Team. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.asakusafw.runtime.value; import java.text.MessageFormat; /** * A light weight class about date. * @see DateUtil * @see DateOption */ public class Date implements Comparable<Date> { /** * The default date format. */ public static final String FORMAT = "yyyy-MM-dd"; //$NON-NLS-1$ private int elapsedDays = 0; /** * Creates a new instance which represents {@code 0001/01/01 (YYYY/MM/DD)}. */ public Date() { this(0); } /** * Creates a new instance. * @param year year (1-...) * @param month month (1-12) * @param day day (1-31) */ public Date(int year, int month, int day) { this(DateUtil.getDayFromDate(year, month, day)); } /** * Creates a new instance. * @param elapsedDays the number of elapsed days from {@code 0001/01/01 (YYYY/MM/DD)} (0-origin) */ public Date(int elapsedDays) { this.elapsedDays = elapsedDays; } /** * Returns the number of elapsed days from {@code 0001/01/01 (YYYY/MM/DD)}. * @return the number of elapsed days (0-origin) */ public int getElapsedDays() { return elapsedDays; } /** * Sets the date as number of elapsed days from {@code 0001/01/01}. * @param elapsed the elapsed days (0-origin) */ public void setElapsedDays(int elapsed) { this.elapsedDays = elapsed; } /** * Returns the year of this date. * @return the year (1-) */ public int getYear() { return DateUtil.getYearFromDay(elapsedDays); } /** * Returns the month of this date. * @return the month (1-12) */ public int getMonth() { int year = getYear(); int dayInYear = elapsedDays - DateUtil.getDayFromYear(year); return DateUtil.getMonthOfYear(dayInYear, DateUtil.isLeap(year)); } /** * Returns the day of this date. * @return the day (1-31) */ public int getDay() { int year = getYear(); int dayInYear = elapsedDays - DateUtil.getDayFromYear(year); return DateUtil.getDayOfMonth(dayInYear, DateUtil.isLeap(year)); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + elapsedDays; return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Date other = (Date) obj; if (elapsedDays != other.elapsedDays) { return false; } return true; } @Override public int compareTo(Date o) { return Integer.compare(elapsedDays, o.elapsedDays); } @Override public String toString() { return String.format( "%04d-%02d-%02d", //$NON-NLS-1$ getYear(), getMonth(), getDay()); } /** * Parses the target string and returns the corresponding date as the elapsed days from * {@code 0001/01/01 (YYYY/MM/DD)}. * @param dateString the target string * @param format the format kind * @return the elapsed days (0-origin) * @throws IllegalArgumentException if the target string is malformed */ public static Date valueOf(StringOption dateString, Date.Format format) { if (dateString == null) { throw new IllegalArgumentException("dateString must not be null"); //$NON-NLS-1$ } if (format == null) { throw new IllegalArgumentException("format must not be null"); //$NON-NLS-1$ } if (dateString.isNull()) { return null; } return valueOf(dateString.getAsString(), format); } /** * Parses the target string and returns the corresponding date object. * @param dateString the target string * @param format the format kind * @return the corresponding date object * @throws IllegalArgumentException if the target string is malformed */ public static Date valueOf(String dateString, Date.Format format) { if (dateString == null) { throw new IllegalArgumentException("dateString must not be null"); //$NON-NLS-1$ } if (format == null) { throw new IllegalArgumentException("format must not be null"); //$NON-NLS-1$ } Date date = new Date(); date.setElapsedDays(format.parse(dateString)); return date; } /** * Represents kinds of date formats. * @since 0.1.0 * @version 0.7.0 */ public enum Format { /** * {@code YYYYMMDD}. */ SIMPLE { @Override public int parse(String dateString) { if (dateString == null) { throw new IllegalArgumentException("dateString must not be null"); //$NON-NLS-1$ } if (dateString.length() != 8) { throw new IllegalArgumentException(MessageFormat.format( "\"{0}\" is not form of \"{1}\"", dateString, "YYYYMMDD")); //$NON-NLS-1$ } int year = get(dateString, 0, 4); int month = get(dateString, 4, 6); int day = get(dateString, 6, 8); return DateUtil.getDayFromDate(year, month, day); } }, /** * {@code YYYY-MM-DD}. * @since 0.7.0 */ STANDARD { @Override public int parse(String dateString) { if (dateString == null) { throw new IllegalArgumentException("dateString must not be null"); //$NON-NLS-1$ } int value = DateUtil.parseDate(dateString, '-'); if (value < 0) { throw new IllegalArgumentException(MessageFormat.format( "\"{0}\" is not form of \"{1}\"", dateString, "YYYY-MM-DD")); //$NON-NLS-1$ } return value; } }, ; /** * Parses the target string and returns the corresponding date as the elapsed days from * {@code 0001/01/01 (YYYY/MM/DD)}. * @param dateString the target string * @return the elapsed days (0-origin) * @throws IllegalArgumentException if the target string is malformed */ public abstract int parse(String dateString); static int get(String string, int from, int to) { return Integer.parseInt(string.substring(from, to)); } } }