DateRange.java

package com.tradecloud.domain.base.utils;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import org.joda.time.DateTime;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;

/**
 * TODO. Maybe make a DateTimeRange class with TemporalType.TIMESTAMP
 */
@Embeddable
@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE, isGetterVisibility = NONE)
public class DateRange implements Serializable {

    @Temporal(TemporalType.DATE)
    @Column(name = "datefrom")
    private Date from;

    @Temporal(TemporalType.DATE)
    @Column(name = "dateto")
    private Date to;

    public DateRange() {
    }

    public DateRange(Date fromDate, Date toDate) {
        this.from = fromDate;
        this.to = toDate;
    }

    public DateRange(Date date, int days) {
        from = new DateTime(date).minusDays(days).toDate();
        to = new DateTime(date).plusDays(days).toDate();
    }

    public Date getFrom() {
        return from;
    }

    public void setFrom(Date from) {
        this.from = from;
    }

    public Date getFromAsStartOfDay() {
        return DateUtils.getStartOfDay(from);
    }

    public Date getTo() {
        return to;
    }

    public void setTo(Date to) {
        this.to = to;
    }

    public Date getToAsEndOfDay() {
        return DateUtils.getEndOfDay(to);
    }

    public boolean inRange(Date date) {
        DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
        String format = df.format(date);
        SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
        Date parsed = null;
        try {
            parsed = sdf.parse(format);
        } catch (ParseException e) {
            e.printStackTrace();
            ;
        }
        return parsed.equals(from) || parsed.equals(to) || (parsed.after(from) && parsed.before(to));
    }

    // Sometimes you need an empty date range, as opposed to a null object because it will be mapped to a to and from date picker on the UI level.
    public boolean isEmpty() {
        return to == null && from == null;
    }

    public boolean isAnyEmpty() {
        return to == null || from == null;
    }

    public void clear() {
        to = null;
        from = null;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        DateRange dateRange = (DateRange) o;

        if (from != null ? !from.equals(dateRange.from) : dateRange.from != null) return false;
        return !(to != null ? !to.equals(dateRange.to) : dateRange.to != null);

    }

    @Override
    public int hashCode() {
        int result = from != null ? from.hashCode() : 0;
        result = 31 * result + (to != null ? to.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Date Range: From '" + from + "'. To '" + to + "'.";
    }
}