/** * 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 and time. * @see DateUtil * @see DateTimeOption */ public class DateTime implements Comparable<DateTime> { /** * The default date and time format. */ public static final String FORMAT = "yyyy-MM-dd HH:mm:ss"; //$NON-NLS-1$ private long elapsedSeconds = 0L; /** * Creates a new instance which represents {@code 0001/01/01 (YYYY/MM/DD) 00:00:00}. */ public DateTime() { this(0L); } /** * Creates a new instance. * @param elapsedSeconds the number of elapsed seconds from {@code 0001/01/01 (YYYY/MM/DD) 00:00:00} (0-origin) */ public DateTime(long elapsedSeconds) { this.elapsedSeconds = elapsedSeconds; } /** * Creates a new instance. * @param year year (1-...) * @param month month (1-12) * @param day day (1-31) * @param hour hour (0-23) * @param minute minute (0-59) * @param second second (0-59) */ public DateTime(int year, int month, int day, int hour, int minute, int second) { int date = DateUtil.getDayFromDate(year, month, day); int secondsInDay = DateUtil.getSecondFromTime(hour, minute, second); this.elapsedSeconds = (long) date * 86400 + secondsInDay; } /** * Returns the number of elapsed seconds from {@code 0001/01/01 (YYYY/MM/DD) 00:00:00}. * @return the number of elapsed seconds (0-origin) */ public long getElapsedSeconds() { return elapsedSeconds; } /** * Sets the date and time as number of elapsed seconds from {@code 0001/01/01 (YYYY/MM/DD) 00:00:00}. * @param elapsed the elapsed seconds (0-origin) */ public void setElapsedSeconds(long elapsed) { this.elapsedSeconds = elapsed; } /** * Returns the year of this date and time. * @return the year (1-) */ public int getYear() { int days = DateUtil.getDayFromSeconds(elapsedSeconds); return DateUtil.getYearFromDay(days); } /** * Returns the month of this date and time. * @return the month (1-12) */ public int getMonth() { int days = DateUtil.getDayFromSeconds(elapsedSeconds); int year = getYear(); int dayInYear = days - DateUtil.getDayFromYear(year); return DateUtil.getMonthOfYear(dayInYear, DateUtil.isLeap(year)); } /** * Returns the day of this date and time. * @return the day (1-31) */ public int getDay() { int year = getYear(); int days = DateUtil.getDayFromSeconds(elapsedSeconds); int dayInYear = days - DateUtil.getDayFromYear(year); return DateUtil.getDayOfMonth(dayInYear, DateUtil.isLeap(year)); } /** * Returns the hour of this date time. * @return the hour (0-23) */ public int getHour() { int sec = DateUtil.getSecondOfDay(elapsedSeconds); return sec / (60 * 60); } /** * Returns the minute of this date time. * @return the minute (0-59) */ public int getMinute() { int sec = DateUtil.getSecondOfDay(elapsedSeconds); return sec / 60 % 60; } /** * Returns the second of this date time. * @return the second (0-59) */ public int getSecond() { int sec = DateUtil.getSecondOfDay(elapsedSeconds); return sec % 60; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (elapsedSeconds ^ (elapsedSeconds >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } DateTime other = (DateTime) obj; if (elapsedSeconds != other.elapsedSeconds) { return false; } return true; } @Override public int compareTo(DateTime o) { return Long.compare(elapsedSeconds, o.elapsedSeconds); } @Override public String toString() { return String.format( "%04d-%02d-%02d %02d:%02d:%02d", //$NON-NLS-1$ getYear(), getMonth(), getDay(), getHour(), getMinute(), getSecond()); } /** * Parses the target string using the specified format, and returns the corresponding date and time as the elapsed * seconds from {@code 0001/01/01 (YYYY/MM/DD) 00:00:00}. * @param timeString the target string * @param format the format kind * @return the elapsed seconds (0-origin) * @throws IllegalArgumentException if the target string is malformed */ public static DateTime valueOf(StringOption timeString, DateTime.Format format) { if (timeString == null) { throw new IllegalArgumentException("timeString must not be null"); //$NON-NLS-1$ } if (format == null) { throw new IllegalArgumentException("format must not be null"); //$NON-NLS-1$ } if (timeString.isNull()) { return null; } return valueOf(timeString.getAsString(), format); } /** * Parses the target string using the specified format, and returns the corresponding date and time object. * @param timeString the target string * @param format the format kind * @return the corresponding date and time object * @throws IllegalArgumentException if the target string is malformed */ public static DateTime valueOf(String timeString, DateTime.Format format) { if (timeString == null) { throw new IllegalArgumentException("timeString must not be null"); //$NON-NLS-1$ } if (format == null) { throw new IllegalArgumentException("format must not be null"); //$NON-NLS-1$ } DateTime time = new DateTime(); time.setElapsedSeconds(format.parse(timeString)); return time; } /** * Represents kinds of date and time formats. * @since 0.1.0 * @version 0.7.0 */ public enum Format { /** * {@code YYYYMMDDhhmmss}. */ SIMPLE { @Override public long parse(String timeString) { if (timeString == null) { throw new IllegalArgumentException("dateString must not be null"); //$NON-NLS-1$ } if (timeString.length() != 14) { throw new IllegalArgumentException(MessageFormat.format( "\"{0}\" is not form of \"{1}\"", timeString, "YYYYMMDDhhmmss")); //$NON-NLS-1$ } int year = get(timeString, 0, 4); int month = get(timeString, 4, 6); int day = get(timeString, 6, 8); int hour = get(timeString, 8, 10); int minute = get(timeString, 10, 12); int second = get(timeString, 12, 14); int date = DateUtil.getDayFromDate(year, month, day); long seconds = (long) date * 86400 + DateUtil.getSecondFromTime(hour, minute, second); return seconds; } }, /** * {@code YYYY-MM-DD hh:mm:ss}. * @since 0.7.0 */ STANDARD { @Override public long parse(String timeString) { if (timeString == null) { throw new IllegalArgumentException("dateString must not be null"); //$NON-NLS-1$ } long value = DateUtil.parseDateTime(timeString, '-', ' ', ':'); if (value < 0) { throw new IllegalArgumentException(MessageFormat.format( "\"{0}\" is not form of \"{1}\"", timeString, "YYYY-MM-DD hh:mm:ss")); //$NON-NLS-1$ } return value; } } ; /** * Parses the target string and returns the corresponding date and time as the elapsed seconds from * {@code 0001/01/01 (YYYY/MM/DD) 00:00:00}. * @param timeString the target string * @return the elapsed seconds (0-origin) * @throws IllegalArgumentException if the target string is malformed */ public abstract long parse(String timeString); static int get(String string, int from, int to) { return Integer.parseInt(string.substring(from, to)); } } }