Last active
August 29, 2015 14:16
-
-
Save danieldietrich/1eb4f62b8f47f51c0662 to your computer and use it in GitHub Desktop.
A Date which is stable regarding hashCode, equals and compareTo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.io.Serializable; | |
| import java.util.Calendar; | |
| import java.util.Date; | |
| import java.util.TimeZone; | |
| /** | |
| * A UTC date, consisting of a year, a month and a day component. Compared to {@linkplain java.util.Date} | |
| * a StableDate is stable regarding {@linkplain java.lang.Object#equals} and {@linkplain java.lang.Object#hashCode}. | |
| */ | |
| public class StableDate implements Comparable<StableDate>, Serializable { | |
| private static final long serialVersionUID = 1L; | |
| private final int year; | |
| private final int month; | |
| private final int day; | |
| /** | |
| * Creates a stable date based on a time in UTC milliseconds. | |
| * @param millis the time in UTC milliseconds from the epoch. | |
| * @return A new StableDate instance | |
| */ | |
| public static StableDate of(long millis) { | |
| // java util date/time stuff is considered to be not thread safe - therefore creating new instances here | |
| final Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); | |
| calendar.setTimeInMillis(millis); | |
| final int year = calendar.get(Calendar.YEAR); | |
| final int month = calendar.get(Calendar.MONTH) + 1; | |
| final int day = calendar.get(Calendar.DAY_OF_MONTH); | |
| return new StableDate(year, month, day); | |
| } | |
| /** | |
| * Creates a stable date based on a UTC {@linkplain java.util.Date}. | |
| * @param date A Date | |
| * @return A new StableDate instance | |
| */ | |
| public static StableDate of(Date date) { | |
| return StableDate.of(date.getTime()); | |
| } | |
| /** | |
| * Constructs a StableDate. | |
| * @param year A year. | |
| * @param month A month, starting with 1. | |
| * @param day A day, starting with 1. | |
| */ | |
| StableDate(int year, int month, int day) { | |
| this.year = year; | |
| this.month = month; | |
| this.day = day; | |
| } | |
| /** | |
| * Gets this year. | |
| * @return this year | |
| */ | |
| public int getYear() { | |
| return year; | |
| } | |
| /** | |
| * Gets this month. | |
| * @return this month | |
| */ | |
| public int getMonth() { | |
| return month; | |
| } | |
| /** | |
| * Gets this day. | |
| * @return this day | |
| */ | |
| public int getDay() { | |
| return day; | |
| } | |
| /** | |
| * Compares this and that StableDate. | |
| * @param that A StableDate, may be null | |
| * @return A negativ number, 0 or a positive number if this date is before, equal or after that date. If that is null, 1 is returned. | |
| */ | |
| @Override | |
| public int compareTo(StableDate that) { | |
| return (that == null) ? 1 : (this.year - that.year) * 10000 + (this.month - that.month) * 100 + (this.day - that.day); | |
| } | |
| /** | |
| * Checks, if o equals this. An object o is equal to this, if o is an instance of StableDate and | |
| * the year, month and day fields of this and o are respectively the same. | |
| * @param o An object, may be null. | |
| * @return true, if o equals this, false otherwise | |
| */ | |
| @Override | |
| public boolean equals(Object o) { | |
| if (o == this) { | |
| return true; | |
| } else if (o instanceof StableDate) { | |
| final StableDate that = (StableDate) o; | |
| return this.year == that.year && this.month == that.month && this.day == that.day; | |
| } else { | |
| return false; | |
| } | |
| } | |
| /** | |
| * Calculates the hash of this StableDate. | |
| * @return {@code year * 10000 + month * 100 + day} | |
| */ | |
| @Override | |
| public int hashCode() { | |
| return year * 10000 + month * 100 + day; | |
| } | |
| /** | |
| * Returns a String representation of this StableDate according to ISO 8601 format 'YYYY-MM-DD'. | |
| * @return This date as String | |
| */ | |
| @Override | |
| public String toString() { | |
| return String.format("%04d-%02d-%02d", year, month, day); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment