/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package fedora.server.utilities;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
/**
* A collection of utility methods for performing frequently required tasks.
*
* @author Ross Wayland
*/
public abstract class DateUtility {
private static final Date ONE_BCE = new Date(-62167392000000L);
private static final Date ONE_CE = new Date(-62135769600000L);
/**
* Converts a datetime string into and instance of java.util.Date using the
* date format: yyyy-MM-ddTHH:mm:ss.SSSZ.
*
* @param dateTime
* A datetime string
* @return Corresponding instance of java.util.Date (returns null if
* dateTime string argument is empty string or null)
*/
public static Date convertStringToDate(String dateTime) {
return parseDateAsUTC(dateTime);
}
/**
* Converts an instance of java.util.Date into a String using the date
* format: yyyy-MM-ddTHH:mm:ss.SSSZ.
*
* @param date
* Instance of java.util.Date.
* @return ISO 8601 String representation (yyyy-MM-ddTHH:mm:ss.SSSZ) of the
* Date argument or null if the Date argument is null.
*/
public static String convertDateToString(Date date) {
return convertDateToString(date, true);
}
/**
* Converts an instance of java.util.Date into an ISO 8601 String
* representation. Uses the date format yyyy-MM-ddTHH:mm:ss.SSSZ or
* yyyy-MM-ddTHH:mm:ssZ, depending on whether millisecond precision is
* desired.
*
* @param date
* Instance of java.util.Date.
* @param millis
* Whether or not the return value should include milliseconds.
* @return ISO 8601 String representation of the Date argument or null if
* the Date argument is null.
*/
public static String convertDateToString(Date date, boolean millis) {
if (date == null) {
return null;
} else {
DateFormat df;
if (millis) {
df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
} else {
df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
}
df.setTimeZone(TimeZone.getTimeZone("UTC"));
if (date.before(ONE_CE)) {
StringBuilder sb = new StringBuilder(df.format(date));
sb.insert(0, "-");
return sb.toString();
} else {
return df.format(date);
}
}
}
/**
* Converts an instance of <code>Date</code> into the canonical lexical
* representation of an XSD dateTime with the following exceptions: - Dates
* before 1 CE (i.e. 1 AD) are handled according to ISO 8601:2000 Second
* Edition: "0000" is the lexical representation of 1 BCE "-0001" is the
* lexical representation of 2 BCE
*
* @param date
* Instance of java.util.Date.
* @return the lexical form of the XSD dateTime value, e.g.
* "2006-11-13T09:40:55.001Z".
* @see <a
* href="http://www.w3.org/TR/xmlschema-2/#date-canonical-representation">3.2.7.2
* Canonical representation</a>
*/
public static String convertDateToXSDString(Date date) {
if (date == null) {
return null;
}
StringBuilder lexicalForm;
String dateTime = convertDateToString(date, true);
int len = dateTime.length() - 1;
if (dateTime.indexOf('.', len - 4) != -1) {
while (dateTime.charAt(len - 1) == '0') {
len--; // fractional seconds may not with '0'.
}
if (dateTime.charAt(len - 1) == '.') {
len--;
}
lexicalForm = new StringBuilder(dateTime.substring(0, len));
lexicalForm.append('Z');
} else {
lexicalForm = new StringBuilder(dateTime);
}
if (date.before(ONE_CE)) {
DateFormat df = new SimpleDateFormat("yyyy");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
StringBuilder year =
new StringBuilder(String.valueOf(Integer.parseInt(df
.format(date)) - 1));
while (year.length() < 4) {
year.insert(0, '0');
}
lexicalForm
.replace(0, lexicalForm.indexOf("-", 4), year.toString());
if (date.before(ONE_BCE)) {
lexicalForm.insert(0, "-");
}
}
return lexicalForm.toString();
}
/**
* Converts an instance of java.util.Date into a String using the date
* format: yyyy-MM-ddZ.
*
* @param date
* Instance of java.util.Date.
* @return Corresponding date string (returns null if Date argument is
* null).
*/
public static String convertDateToDateString(Date date) {
if (date == null) {
return null;
} else {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'Z'");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
return df.format(date);
}
}
/**
* Converts an instance of java.util.Date into a String using the date
* format: HH:mm:ss.SSSZ.
*
* @param date
* Instance of java.util.Date.
* @return Corresponding time string (returns null if Date argument is
* null).
*/
public static String convertDateToTimeString(Date date) {
if (date == null) {
return null;
} else {
DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS'Z'");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
return df.format(date);
}
}
/**
* Attempt to parse the given string of form: yyyy-MM-dd[THH:mm:ss[.SSS][Z]]
* as a Date. If the string is not of that form, return null.
*
* @param dateString
* the date string to parse
* @return Date the date, if parse was successful; null otherwise
*/
public static Date parseDateAsUTC(String dateString) {
if (dateString == null || dateString.length() == 0) {
return null;
}
SimpleDateFormat formatter = new SimpleDateFormat();
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
int length = dateString.length();
if (dateString.startsWith("-")) {
length--;
}
if (dateString.endsWith("Z")) {
if (length == 11) {
formatter.applyPattern("yyyy-MM-dd'Z'");
} else if (length == 20) {
formatter.applyPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
} else if (length == 22) {
formatter.applyPattern("yyyy-MM-dd'T'HH:mm:ss.S'Z'");
} else if (length == 23) {
formatter.applyPattern("yyyy-MM-dd'T'HH:mm:ss.SS'Z'");
} else if (length == 24) {
formatter.applyPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
}
} else {
if (length == 10) {
formatter.applyPattern("yyyy-MM-dd");
} else if (length == 19) {
formatter.applyPattern("yyyy-MM-dd'T'HH:mm:ss");
} else if (length == 21) {
formatter.applyPattern("yyyy-MM-dd'T'HH:mm:ss.S");
} else if (length == 22) {
formatter.applyPattern("yyyy-MM-dd'T'HH:mm:ss.SS");
} else if (length == 23) {
formatter.applyPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
} else if (dateString.endsWith("GMT") || dateString.endsWith("UTC")) {
formatter.applyPattern("EEE, dd MMMM yyyyy HH:mm:ss z");
}
}
try {
return formatter.parse(dateString);
} catch (ParseException e) {
return null;
}
}
}