package co.codewizards.cloudstore.core.dto;
import static co.codewizards.cloudstore.core.util.AssertUtil.assertNotNull;
import java.util.Date;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import co.codewizards.cloudstore.core.dto.jaxb.DateTimeXmlAdapter;
import co.codewizards.cloudstore.core.util.ISO8601;
import co.codewizards.cloudstore.core.util.Util;
/**
* Immutable representation of a timestamp (a date and a time).
* <p>
* This object serves as a Dto both inside XML and in URLs (usually as
* a query parameter, but it may be used inside a path, too). For this
* purpose, its {@link #toString()} method and its {@linkplain #DateTime(String) single-String-argument-constructor}
* are used.
* @author Marco หงุ่ยตระกูล-Schulze - marco at codewizards dot co
*/
@XmlJavaTypeAdapter(type=DateTime.class, value=DateTimeXmlAdapter.class)
public class DateTime {
private final Date date;
/**
* Creates a new instance from the given ISO-8601-encoded {@code dateString}.
* <p>
* The result of the {@link #toString()} method can be passed to this constructor
* to obtain a copy of the original {@code DateTime} instance. This feature should
* be used to transport ISO-8601-encoded timestamps over the network:
* <p>
* <pre> DateTime original = new DateTime(new Date());
* String iso8601encoded = original.toString();
* // iso8601encoded could now be transported to a remote machine as part of a
* // REST URL (e.g. as query parameter).
*
* // The remote machine might then decode it using this REST-conform constructor:
* DateTime copy = new DateTime(iso8601encoded);</pre>
* <p>
* Because of this constructor, {@code DateTime} parameters can be directly used in
* REST resource (a.k.a. service) methods.
* @param dateString the ISO-8601-encoded form of a timestamp. Must not be <code>null</code>.
* @see #toString()
*/
public DateTime(String dateString) {
date = ISO8601.parseDate(assertNotNull(dateString, "dateString"));
}
/**
* Creates a new instance from the given {@code date}.
* <p>
* Because {@link Date} instances are mutable, the given {@code date} is cloned.
* This way it can be guaranteed that {@code DateTime} instances are immutable.
* @param date the date to be cloned and wrapped in the new {@code DateTime} instance. Must not be <code>null</code>.
*/
public DateTime(Date date) {
this.date = (Date) assertNotNull(date, "date").clone();
}
/**
* Gets the number of milliseconds since 1970 January 1 00:00:00 GMT represented by this {@code DateTime} object.
* @return the number of milliseconds since 1970 January 1 00:00:00 GMT represented by this {@code DateTime} object.
* @see Date#getTime()
*/
public long getMillis() {
return date.getTime();
}
@Override
public int hashCode() {
return date == null ? 0 : date.hashCode();
}
@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;
return Util.equal(this.date, other.date);
}
/**
* Returns an ISO-8601-encoded timestamp which can be passed to {@link #DateTime(String)}.
* <p>
* <b><u>Inherited javadoc:</u></b>
* <p>
* {@inheritDoc}
* @see #DateTime(String)
*/
@Override
public String toString() {
return ISO8601.formatDate(date);
}
/**
* Converts this {@code DateTime} into a new {@link Date} instance.
* @return a new {@link Date} instance representing the same timestamp as this {@code DateTime}. Never <code>null</code>.
*/
public Date toDate() {
return (Date) date.clone();
}
}