Skip to content

Instantly share code, notes, and snippets.

@amoerie
Created November 3, 2015 09:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amoerie/b4a2631e4064ea89768e to your computer and use it in GitHub Desktop.
Save amoerie/b4a2631e4064ea89768e to your computer and use it in GitHub Desktop.
Very simple datetime for Java (minimal port from C#)
public class DateTime implements Cloneable, Comparable<DateTime>,Parcelable {
public static DateTime today() { return now().withTimeAtStartOfDay(); }
public static DateTime now() { return new DateTime(Calendar.getInstance()); }
private final Calendar calendar;
@Override
public int compareTo(@NonNull DateTime another) {
return calendar.compareTo(another.calendar);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return new DateTime((Calendar) calendar.clone());
}
public DateTime(int year, int month, int dayOfMonth) {
this.calendar = new GregorianCalendar(year, month, dayOfMonth);
}
public DateTime(int year, int month, int dayOfMonth, int hour, int minute, int seconds) {
this.calendar = new GregorianCalendar(year, month, dayOfMonth, hour, minute, seconds);
}
public DateTime(Calendar calendar) {
if(calendar == null) throw new IllegalArgumentException("Calendar cannot be null");
this.calendar = calendar;
}
public DateTime(Date date) {
if(date == null) throw new IllegalArgumentException("Date cannot be null");
this.calendar = new GregorianCalendar();
this.calendar.setTime(date);
}
private DateTime newDateTime(CalendarChanger calendarChanger) {
Calendar clone = (Calendar) calendar.clone();
calendarChanger.change(clone);
return new DateTime(clone);
}
/**
* @return the day of the month, ranging between 1 - 31 (depending on the month)
*/
public int getDayOfMonth() {
return calendar.get(Calendar.DAY_OF_MONTH);
}
/**
* See Calendar.MONDAY, Calendar.TUESDAY, ...
* @return the day of the week, ranging between 1 - 7 where 1 is Sunday and 7 is Saturday.
*/
public int getDayOfWeek() {
return calendar.get(Calendar.DAY_OF_WEEK);
}
/**
* @return the day of the year, ranging between 1 and 365
*/
public int getDayOfYear() {
return calendar.get(Calendar.DAY_OF_YEAR);
}
/**
* See Calendar.JANUARY, Calendar.FEBRUARY, ...
* @return the month, ranging between 0 and 11 where 0 is January and 11 is December.
*/
public int getMonth() {
return calendar.get(Calendar.MONTH);
}
/**
* @return the year
*/
public int getYear() {
return calendar.get(Calendar.YEAR);
}
/**
* @param days the number of days to add (can be negative)
* @return a new DateTime offset with the provided days
*/
public DateTime addDays(final int days) {
return newDateTime(new CalendarChanger() {
@Override
public void change(Calendar calendar) {
calendar.add(Calendar.DATE, days);
}
});
}
/**
* @param months the number of months to add (can be negative)
* @return a new DateTime offset with the provided months
*/
public DateTime addMonths(final int months) {
return newDateTime(new CalendarChanger() {
@Override
public void change(Calendar calendar) {
calendar.add(Calendar.MONTH, months);
}
});
}
/**
* @param years the number of years to add (can be negative)
* @return a new DateTime offset with the provided years
*/
public DateTime addYears(final int years) {
return newDateTime(new CalendarChanger() {
@Override
public void change(Calendar calendar) {
calendar.add(Calendar.YEAR, years);
}
});
}
/**
* @return a new DateTime with all the time fields set to zero (essentially turning back the clock to midnight)
*/
public DateTime withTimeAtStartOfDay() {
return newDateTime(new CalendarChanger() {
@Override
public void change(Calendar calendar) {
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
}
});
}
/**
* @param other the other DateTime
* @return true if this instance is even just a millisecond before the other datetime or false otherwise
*/
public boolean isBefore(DateTime other) {
return this.calendar.compareTo(other.calendar) < 0;
}
/**
* @param other the other DateTime
* @return true if this instance is even just a millisecond after the other datetime or false otherwise
*/
public boolean isAfter(DateTime other) {
return this.calendar.compareTo(other.calendar) > 0;
}
/**
* @param other the other DateTime
* @return true if this instance has the exact same date fields (year, month, day) as the other datetime or false otherwise
*/
public boolean isSameDayAs(DateTime other) {
return this.getYear() == other.getYear()
&& this.getDayOfYear() == other.getDayOfYear();
}
/**
* @return a new Calendar representing the same date as this DateTime
*/
public Calendar toCalendar() {
return (Calendar) calendar.clone();
}
/**
* @return a new Date representing the same date as this DateTime
*/
public Date toDate() {
return calendar.getTime();
}
public long toTimeInMilliseconds() { return calendar.getTimeInMillis(); }
@Override
public String toString() {
return "DateTime{" +
DateTimeFormat.ISO_8601.format(this) +
'}';
}
private interface CalendarChanger {
public void change(Calendar calendar);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeSerializable(this.calendar);
}
private DateTime(Parcel in) {
this.calendar = (Calendar) in.readSerializable();
}
public static final Parcelable.Creator<DateTime> CREATOR = new Parcelable.Creator<DateTime>() {
public DateTime createFromParcel(Parcel source) {
return new DateTime(source);
}
public DateTime[] newArray(int size) {
return new DateTime[size];
}
};
}
public class DateTimeFormat {
public static final DateTimeFormat VERY_LONG = new DateTimeFormat("EEEE d MMMM yyyy");
public static final DateTimeFormat ISO_8601 = new DateTimeFormat("yyyy-MM-dd'T'HH:mm'Z'");
public static DateTimeFormat getTimeFormat(Context context) {
return new DateTimeFormat(android.text.format.DateFormat.getTimeFormat(context));
}
private final DateFormat dateFormat;
public DateTimeFormat(DateFormat dateFormat) {
if(dateFormat == null) {
throw new IllegalArgumentException("Cannot create a DateTimeFormat without a format specified: dateFormat cannot be null");
}
this.dateFormat = dateFormat;
}
/**
* Creates a new DateTimeFormat with the given format string and the specified locale
* @param format the format to be used, see http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html for options
*/
public DateTimeFormat(String format, Locale locale) {
this(new SimpleDateFormat(format, locale));
}
/**
* Creates a new DateTimeFormat with the given format string and the user preferred locale
* @param format the format to be used, see http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html for options
*/
public DateTimeFormat(String format) {
this(format, Locale.getDefault());
}
public String format(DateTime dateTime) {
return dateFormat.format(dateTime.toDate());
}
public DateTime parse(String formattedDateTime) throws ParseException {
Date date = dateFormat.parse(formattedDateTime);
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
return new DateTime(calendar);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment