at.spardat.enterprise.util.DateUtil Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
// @(#) $Id: DateUtil.java 2093 2007-11-28 14:23:36Z s3460 $
package at.spardat.enterprise.util;
import java.util.GregorianCalendar;
import java.util.Calendar;
/**
* Some date utility functions. The valid date range is [1.1.0001, 31.12.9999], whereby the
* range [5.10.1582, 14.10.1582] is excluded. Until 4.10.1582, the Julian calendar is used
* (every 4th year is a leap year). Beginning at 15.10.1582, the Gregorian calender is put
* into action (still every 4th year is a leap year, without every 100th, and the exception
* from the exception is every 400th).
*
* Many of the methods use string representations to denote a date, the format used is at any time
* YYYYMMDD.
*/
public class DateUtil {
// max of days in month at index i
private static final int[] daysInMonth = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
/**
* Represents the components of a date.
*/
static public class DMY {
/**
* The day component, [1..31]
*/
public int d_;
/**
* The month component, [1..12]
*/
public int m_;
/**
* The year component, [1..9999]
*/
public int y_;
}
/**
* Calculates if a year is a leap year.
*
* @param year the input year
* @return true if leap year
*/
public static boolean isLeapYear (int year) {
return year >= 1582 ?
((year%4 == 0) && ((year%100 != 0) || (year%400 == 0))) : // Gregorian
(year%4 == 0); // Julian
}
/**
* Returns true if the provided components represent a valid date
*/
public static boolean isValid (DMY dmy) {
if (dmy.y_ < 1 || dmy.y_ > 9999) return false;
if (dmy.y_ == 1582) {
// range from 5.10.1582 to 14.10.1582 is excluded
if (dmy.m_ == 10) {
if (dmy.d_ >= 5 && dmy.d_ <= 14) return false;
}
}
if (dmy.m_ < 1 || dmy.m_ > 12) return false;
if (dmy.d_ < 1 || dmy.d_ > daysInMonth[dmy.m_]) return false;
if (dmy.m_ == 2) {
// check for 29th of february
if (dmy.d_ == 29 && !isLeapYear(dmy.y_)) return false;
}
return true;
}
/**
* Returns components out of GregorianCalendar.
*
* @param c the input calendar
* @return a newly created DMY object
*/
public static DMY getDMY (GregorianCalendar c) {
DMY dmy = new DMY();
dmy.y_ = c.get(Calendar.YEAR);
dmy.m_ = c.get(Calendar.MONTH)+1;
dmy.d_ = c.get(Calendar.DAY_OF_MONTH);
return dmy;
}
/**
* Converts a java.util.Date to the internal format
*/
public static String date2Internal (java.util.Date d) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(d);
return DMY2Internal(getDMY(cal));
}
/**
* Converts the internal date format to a java.util.Date
*/
public static java.util.Date internal2Date (String internal) {
return internal2Gregorian(internal).getTime();
}
/**
* Converts the ISO string YYYYMMDD to the components. Requires that internal is exactly
* 8 digits and that all digits are indeed digits.
*
* @param internal string following YYYYMMDD with isValid yielding true.
* @return newly created DMY object
*/
public static DMY internal2DMY (String internal) {
DMY dmy = new DMY();
dmy.y_ = (((internal.charAt(0)-'0')*10+internal.charAt(1)-'0')*10+internal.charAt(2)-'0')*10+internal.charAt(3)-'0';
dmy.m_ = (internal.charAt(4)-'0')*10+internal.charAt(5)-'0';
dmy.d_ = (internal.charAt(6)-'0')*10+internal.charAt(7)-'0';
return dmy;
}
/**
* Checks if the provided String is a valid YYYYMMDD string. The syntax must be ok and
* the date must within the defined date range.
*/
public static boolean isValid (String internal) {
if (internal == null) return false;
if (internal.length() != 8) return false;
for (int i=7; i>=0; i--) if (!NumberUtil.isDigit(internal.charAt(i))) return false;
DateUtil.DMY dmy = DateUtil.internal2DMY(internal);
return DateUtil.isValid (dmy);
}
/**
* Converts an YYYMMDD string to a newly created GregorianCalendar.
*
* @param internal string following the syntax YYYYMMDD
* @return newly created GregorianCalendar
*/
public static GregorianCalendar internal2Gregorian (String internal) {
DMY dmy = internal2DMY(internal);
GregorianCalendar c = new GregorianCalendar(dmy.y_, dmy.m_-1, dmy.d_);
return c;
}
/**
* Converts a DMY structure to the ISO format YYYYMMDD
*
* @param the input DMY object
* @return string following YYYYMMDD
*/
public static String DMY2Internal (DMY dmy) {
StringBuffer b = new StringBuffer(8);
NumberUtil.appendIntString (dmy.y_, 4, b);
NumberUtil.appendIntString (dmy.m_, 2, b);
NumberUtil.appendIntString (dmy.d_, 2, b);
return b.toString();
}
/**
* Sets the time in the given cal to 00:00:00.000
*/
public static void resetTime (GregorianCalendar cal) {
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
}
}