fatherazrael
fatherazrael

Reputation: 5977

How to format as well as compare DateTime(if one date is null) in Java 8?

How to modify following Date Comparison using Java 8 which reduce whole these methods into less lines which includes Null Safety too?

//Format and convert to date
private static Date handleDate(String dateInString) {
    if(dateInString == null) {
        return null;
    }
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    try {
        return formatter.parse(dateInString);
    } catch (ParseException e) {
        e.printStackTrace();
        return null;
    }
}

//Checks if dates are equal
private static boolean dateEquals(Date date1, Date date2) {
    if (date1 == null && date2 != null) {
        return false;
    }
    if (date2 == null && date1 != null) {
        // We already have data, don't want null there then.
        return false;
    }

    if (date1 != null && date2 != null) {
        if(date1.equals(date2)) {
            return true;
        }
    }
    return false;
}

//Main
public static void main(String[] args) {

    Date current = handleDate("2019-09-02T00:00:00");
    Date existing = handleDate("2019-09-02T01:00:00");

    System.out.println(dateEquals(existing, current));

Also I do not want to have null check, so is there any utility doing so?

Upvotes: 1

Views: 10327

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 338516

Avoid Date class

You are using the wrong date-time class. Date was supplanted years ago by the modern java.time classes defined in JSR 310. And that class represents a moment in UTC, but your input lacks the context of an offset-from-UTC or time zone.

LocalDateTime

The LocalDateTime class is appropriate to represent a date and a time-of-day lacking any context of time zone or offset-from-UTC.

Your input is in standard ISO 8601 format. The java.time classes use these formats by default when parsing/generating text.

LocalDateTime x = LocalTimeDate.parse( "2019-09-02T00:00:00" ) ;

Compare as shown in the other Answer.

int result =  Objects.equals( x , y ) ;

Tolerating nulls

If you want to tolerate nulls in your input string, write your own wrapper around parsing. Return an Optional possibly containing a LocalDateTime. If your are new to Optional, do not get all excited and go sprinkling them throughout your codebase. That class is intended only for return values.

public Optional < LocalDateTime > parsePossibleNull ( String input )
{
    LocalDateTime ldt = null;
    if ( Objects.isNull( input ) )
    {
        return Optional.ofNullable( ldt );
    } else
    {
        try
        {
            ldt = LocalDateTime.parse( input );
            return Optional.of( ldt );
        } catch ( DateTimeParseException e )
        {
            return Optional.ofNullable( ldt );
        }
    }
}

⚠ Tolerating nulls is unwise

This much toleration of nulls is likely unwise. While your code should be defensive against invalid inputs, parsing/handling code should generally not take responsibility for such poor inputs, nor should it pass faulty inputs along the chain. Usually it is much wiser to reject bad input as early as possible, throwing an exception if need be.

Optional types are comparable

But if you insist, you can compare the Optional<LocalDateTime> objects.

To quote the Javadoc:

The other object is considered equal if:

• it is also an Optional and;

• both instances have no value present or;

• the present values are "equal to" each other via equals().

Try it.

String x = "2019-09-02T00:00:00";
String y = null; // "2019-09-02T01:00:00";

Optional < LocalDateTime > xOpt = this.parsePossibleNull( x );
Optional < LocalDateTime > yOpt = this.parsePossibleNull( y );

boolean same = Objects.equals( xOpt , yOpt );

System.out.println( "xOpt = " + xOpt );
System.out.println( "yOpt = " + yOpt );
System.out.println( "same: " + same );

xOpt = Optional[2019-09-02T00:00]

yOpt = Optional.empty

same: false

…and…

xOpt = Optional[2019-09-02T00:00]

yOpt = Optional[2019-09-02T01:00]

same: false

…and…

xOpt = Optional[2019-09-02T00:00]

yOpt = Optional[2019-09-02T00:00]

same: true

Upvotes: 3

mtj
mtj

Reputation: 3554

For null-tolerant comparisons: java.util.Objects.equals(date1, date2) (since Java 7)

For formatting I'm not aware of any such utility.

Upvotes: 4

Related Questions