summaryrefslogtreecommitdiff
path: root/src/main/java/at/gv/util/DateTimeUtil.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/gv/util/DateTimeUtil.java')
-rw-r--r--src/main/java/at/gv/util/DateTimeUtil.java358
1 files changed, 358 insertions, 0 deletions
diff --git a/src/main/java/at/gv/util/DateTimeUtil.java b/src/main/java/at/gv/util/DateTimeUtil.java
new file mode 100644
index 0000000..c301685
--- /dev/null
+++ b/src/main/java/at/gv/util/DateTimeUtil.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2011 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * 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 at.gv.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.lang.time.DateUtils;
+import org.apache.commons.validator.GenericTypeValidator;
+import org.apache.commons.validator.GenericValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author <a href="mailto:thomas.knall@iaik.tugraz.at">Thomas Knall</a>
+ */
+public final class DateTimeUtil {
+
+ private static Logger log = LoggerFactory.getLogger(DateTimeUtil.class);
+ public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
+ public static final String DEFAULT_TIME_PATTERN = "HH:mm:ss";
+ public static final String DEFAULT_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS";
+
+ public static int calcAge(Calendar dateOfBirth, Calendar now) {
+ int age = now.get(Calendar.YEAR) - dateOfBirth.get(Calendar.YEAR);
+
+ int nowM = now.get(Calendar.MONTH);
+ int dobM = dateOfBirth.get(Calendar.MONTH);
+ int nowDOM = now.get(Calendar.DAY_OF_MONTH);
+ int dobDOM = dateOfBirth.get(Calendar.DAY_OF_MONTH);
+
+ if ((nowM < dobM) || ((nowM == dobM) && (nowDOM < dobDOM))) {
+ age--;
+ }
+
+ if (age < 0) {
+ throw new IllegalArgumentException(
+ "Calculated age results in negative value.");
+ }
+ return age;
+ }
+
+ public static int calcAge(Calendar dateOfBirth) {
+ return calcAge(dateOfBirth, Calendar.getInstance());
+ }
+
+ public static int calcAge(Date dateOfBirth, Date now) {
+ Calendar dob = Calendar.getInstance();
+ dob.setTime(dateOfBirth);
+ Calendar nowCal = Calendar.getInstance();
+ nowCal.setTime(now);
+ return calcAge(dob, nowCal);
+ }
+
+ public static int calcAge(Date dateOfBirth) {
+ return calcAge(dateOfBirth, new Date());
+ }
+
+ public static Date parseDate(String dateString, String datePattern,
+ String checkRegExpPattern) {
+ Date returnDate = null;
+ if (!MiscUtil.isEmpty(checkRegExpPattern)) {
+ if (!GenericValidator.matchRegexp(dateString, checkRegExpPattern)) {
+ return null;
+ }
+ }
+ if (MiscUtil.isEmpty(datePattern)) {
+ datePattern = DEFAULT_DATE_PATTERN;
+ }
+ if (GenericValidator.isDate(dateString, datePattern, false)) {
+ returnDate = GenericTypeValidator.formatDate(dateString, datePattern,
+ false);
+ }
+ return returnDate;
+ }
+
+ public static Date mergeDateTime(Date date, Date time) {
+ if (MiscUtil.areAllNull(date, time)) {
+ throw new NullPointerException(
+ "Date and time must not be null at the same time.");
+ }
+ if (date == null) {
+ return time;
+ }
+ if (time == null) {
+ return date;
+ }
+ Calendar dateCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ dateCal.setTime(date);
+ Calendar timeCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ timeCal.setTime(time);
+ dateCal.set(Calendar.HOUR_OF_DAY, timeCal.get(Calendar.HOUR_OF_DAY));
+ dateCal.set(Calendar.MINUTE, timeCal.get(Calendar.MINUTE));
+ dateCal.set(Calendar.SECOND, timeCal.get(Calendar.SECOND));
+ dateCal.set(Calendar.MILLISECOND, timeCal.get(Calendar.MILLISECOND));
+ return dateCal.getTime();
+ }
+
+ public static Date parseDate(String dateString, String datePattern) {
+ return parseDate(dateString, datePattern, null);
+ }
+
+ public static boolean equalsIgnoreMilliseconds(Date date1, Date date2) {
+ if (date1 == date2) {
+ return true;
+ }
+ if (date1 == null || date2 == null) {
+ return false;
+ }
+ return DateUtils.truncate(date1, Calendar.SECOND).equals(
+ DateUtils.truncate(date2, Calendar.SECOND));
+ }
+
+ public static Date parseDate(String dateString) {
+ return parseDate(dateString, null, null);
+ }
+
+ public static Date parseTime(String timeString) {
+ return parseDate(timeString, DEFAULT_TIME_PATTERN, null);
+ }
+
+ public static String formatXMLDateTimeString(Date date) {
+ if (date == null) {
+ return "null";
+ }
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.get(Calendar.MILLISECOND);
+ return DateFormatUtils.format(date,
+ cal.get(Calendar.MILLISECOND) == 0 ? "yyyy-MM-dd'T'HH:mm:ssZZ"
+ : "yyyy-MM-dd'T'HH:mm:ss.SSSZZ");
+ }
+
+ public static String formatUTCDateTimeString(Date date) {
+ if (date == null) {
+ return "null";
+ }
+ return DateFormatUtils.formatUTC(date, "yyyy-MM-dd'T'HH:mm:ss'Z'");
+ }
+
+ /**
+ * <p>
+ * Parses a datetime according to ISO 8601.
+ * </p>
+ *
+ * <p>
+ * Complete date plus hours and minutes<br/>
+ * YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
+ * </p>
+ *
+ * <p>
+ * Complete date plus hours, minutes and seconds<br/>
+ * YYYY-MM-DDThh:mm:ssTZD(eg 1997-07-16T19:20:30+01:00)
+ * </p>
+ *
+ * <p>
+ * Complete date plus hours, minutes, seconds and a decimal fraction of a
+ * second<br/>
+ * YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
+ * </p>
+ *
+ * <p>
+ * where:
+ * </p>
+ *
+ * YYYY = four-digit year<br/>
+ * MM = two-digit month (01=January, etc.)<br/>
+ * DD = two-digit day of month (01 through 31)<br/>
+ * hh = two digits of hour (00 through 23) (am/pm NOT allowed)<br/>
+ * mm = two digits of minute (00 through 59)<br/>
+ * ss = two digits of second (00 through 59)<br/>
+ * s = one or more digits representing a decimal fraction of a second<br/>
+ * TZD = time zone designator (Z or +hh:mm or -hh:mm)<br/>
+ *
+ * @see <a
+ * href="http://www.w3.org/TR/NOTE-datetime">http://www.w3.org/TR/NOTE-datetime</a>
+ * @param dtText
+ * The date.
+ * @param noTimeZoneMeansUTC
+ * @return The parsed date.
+ * @throws ParseException
+ */
+ public static Date parseXMLDateTimeString(String dtText,
+ boolean noTimeZoneMeansUTC) throws ParseException {
+ if (dtText == null) {
+ throw new NullPointerException("Provided date text must not be null.");
+ }
+ String[] parsePatterns = { "yyyy-MM-dd'T'HH:mm:ss",
+ "yyyy-MM-dd'T'HH:mm:ssZZ", "yyyy-MM-dd'T'HH:mm:ss.SSSZZ",
+ "yyyy-MM-dd'T'HH:mm:ss.SSS" };
+
+ // TODO: fix hack
+
+ if (dtText.length() > 19) {
+ int li = dtText.lastIndexOf(":");
+ if (li >= 19) {
+ dtText = new StringBuffer(dtText).deleteCharAt(li).toString();
+ }
+ if (dtText.endsWith("Z")) {
+ dtText = StringUtils.chop(dtText) + "UTC";
+ }
+ } else if (noTimeZoneMeansUTC) {
+ log.debug("UTC can be applied because no other offset has been provided.");
+ dtText += "UTC";
+ }
+ return DateUtils.parseDate(dtText, parsePatterns);
+ }
+
+ public static Date parseXMLDateTimeString(String dtText)
+ throws ParseException {
+ return parseXMLDateTimeString(dtText, false);
+ }
+
+ public static String getDatePattern(String languageCode) {
+ String datePattern = DEFAULT_DATE_PATTERN;
+ if (languageCode != null) {
+
+ if ("de".equalsIgnoreCase(languageCode)) {
+ datePattern = "dd.MM.yyyy";
+ } else if ("en".equalsIgnoreCase(languageCode)) {
+ datePattern = "yyyy-MM-dd";
+ } else {
+ log.warn("language code \"" + languageCode
+ + "\" notsupported; using failsafe pattern \"" + datePattern + "\"");
+ }
+ }
+ return datePattern;
+ }
+
+ public static String formatDate(Date date, String datePattern) {
+ if (date == null) {
+ throw new NullPointerException("date must not be null");
+ }
+ SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
+ return sdf.format(date);
+ }
+
+ public static String formatDate(Date date) {
+ return formatDate(date, getDatePattern(null));
+ }
+
+ public static String formatTime(Date time) {
+ return formatDate(time, DEFAULT_TIME_PATTERN);
+ }
+
+ /**
+ * Checks if the given reference date ({@code pReference}) is valid according
+ * to the given date constraints {@code from} and {@code to}. The validation
+ * uses an intuitive approach including {@code from} and {@code to} ignoring
+ * the time component of the date objects:<br/>
+ * e.g. {@code from=2008-09-09}, {@code to=2010-09-08}<br/>
+ * valid reference dates: {@code 2008-09-09T00:00:00.000},
+ * {@code 2008-09-09T12:34:50.000}, {@code 2010-09-08T00:00:00.000},
+ * {@code 2010-09-08T23:59:59.999}
+ *
+ * @param from
+ * The date the validity period starts from (inclusive ignoring time
+ * component).
+ * @param to
+ * The date the validity period starts from (inclusive ignoring time
+ * component).
+ * @param pReference
+ * The date to be validated.
+ * @return {@code true} if the reference date is valid, {@code false} if not.
+ * @throws CheckException
+ * Thrown if the given reference date could not be validated.
+ * @author <a href="mailto:thomas.knall@iaik.tugraz.at">Thomas Knall</a>
+ */
+ public static boolean validateDateConstraint(Date from, Date to,
+ Date pReference) {
+ if (pReference == null) {
+ throw new NullPointerException(
+ "Reference date needed to verify time constraints.");
+ }
+ Calendar fromCal = null;
+ if (from != null) {
+ fromCal = Calendar.getInstance();
+ fromCal.setTime(from);
+ fromCal = removeTimeComponent(fromCal);
+ }
+ Calendar toCal = null;
+ if (to != null) {
+ toCal = Calendar.getInstance();
+ toCal.setTime(to);
+ toCal = removeTimeComponent(toCal);
+ }
+ Calendar refCal = Calendar.getInstance();
+ refCal.setTime(pReference);
+ refCal = removeTimeComponent(refCal);
+
+ if ((fromCal != null && refCal.before(fromCal))
+ || (toCal != null && refCal.after(toCal))) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes the time component from a date object returning a new date
+ * instance.
+ *
+ * @param cal
+ * The original date object.
+ * @return A new date object (without time component).
+ * @author <a href="mailto:thomas.knall@egiz.gv.at">Thomas Knall</a>
+ */
+ public static Date removeTimeComponent(Date date) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ return removeTimeComponent(cal).getTime();
+ }
+
+ /**
+ * Removes the time component from a calendar object returning a new calendar
+ * instance.
+ *
+ * @param cal
+ * The original calendar object.
+ * @return A new calendar object (without time component).
+ * @author <a href="mailto:thomas.knall@egiz.gv.at">Thomas Knall</a>
+ */
+ public static Calendar removeTimeComponent(Calendar cal) {
+ Calendar newCal = (Calendar) cal.clone();
+ newCal.set(Calendar.HOUR_OF_DAY, 0);
+ newCal.set(Calendar.MINUTE, 0);
+ newCal.set(Calendar.SECOND, 0);
+ newCal.set(Calendar.MILLISECOND, 0);
+ return newCal;
+ }
+
+ public static String formatTimeStamp(Date timestamp) {
+ return formatDate(timestamp, DEFAULT_TIMESTAMP_PATTERN);
+ }
+
+ private DateTimeUtil() {
+ }
+
+}