-1

I have an issue on checking future date at the server. Since Date.parse() parse differently under chrome and Firefox. Under Firefox, a negative date time is passed to the server. Since I want to avoid this kind of browser problem, I tried to implement a validation on server side.

Date currentDate = new Date();
Date interviewingDate = interview.getInterviewingDate();
LocalDateTime currentDateTime = convertToLocalDateTime(currentDate);
LocalDateTime interviewingDateTime = convertToLocalDateTime(interview.getInterviewingDate());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedCurrentDateTime = currentDateTime.format(formatter);
String formattedInterviewDateTime = interviewingDateTime.format(formatter);

I tried to compare the server time with the case interviewing time. Since the future day is not allowed, if(interviewingDateTime.isAfter(currentDateTime)) return -1

But when I test it, the result is not I expected.

Here's some log:
currentDateTime.getTime() 1607592350160
interviewingDateTime.getTime() -125883137443000

formattedCurrentDateTime 2020-12-10 17:25:50
formattedInterviewDateTime 2021-12-03 13:55:00

currentDateTime toLocalDate 2020-12-10
interviewingDateTime toLocalDate -2020-12-03
interviewingDateTime.toLocalTime()13:55
currentDateTime.toLocalTime() 17:25:50.160

interviewingDateTime.isAfter(currentDateTime): false
interviewingDate.compareTo(currentDate): -1

I expect isAfter returns true since interviewing time is a future date. And I see there's negative value when I tried to output the local date and the original Date object getTime(). Is there anyway to convert the negative to back to normal positive date ? Or any other way to compare and check the date is future date as expected ?

Jon Skeet
  • 1,335,956
  • 823
  • 8,931
  • 9,049
azrael3192
  • 37
  • 4
  • 1
    We don't know how `interviewingDate` is being derived. The value you've given is in 1966, which seems unlikely to be correct. I would start there - nothing after that matters until you've got the right value there. I would really, really try to avoid using `java.util.Date` at all though. – Jon Skeet Dec 10 '20 at 10:05
  • 1
    Separately, you're talking about `Date.parse()` and Chrome vs Firefox - but that's Javascript code, not Java. I strongly suspect you should avoid parsing the date in the browser at all - just send an ISO-8601 text representation and parse it server-side. – Jon Skeet Dec 10 '20 at 10:05
  • I am using hibernate mapping the date, so the front end is passing the date value as -125883137443000. But why the formatted string date is correct? – azrael3192 Dec 10 '20 at 10:21
  • 2
    I can't tell, because you haven't shown `convertToLocalDateTime`. This is where a [mcve] would make it a lot easier to help you. But unless the value is *really* meant to represent a date in 1966, the first thing you need to fix is the frontend, possibly changing it to pass a textual representation instead of a number. (We don't know where the information is coming from - is this user input?) There's so much we don't know here, it's hard to help you. – Jon Skeet Dec 10 '20 at 10:26
  • -125883137443000 milliseoncds (so 125 883 137 443 seconds *before* the epoch) is in year 2021 BCE alright. Before the common era, “before Christ”. How you got that value I can’t tell. – Ole V.V. Dec 12 '20 at 08:58
  • @JonSkeet Year 1966 assumes the number denotes microseconds. I believe they are milliseconds. – Ole V.V. Dec 12 '20 at 09:00
  • @OleV.V.: Whoops, you're right. I misread epochconverter.com. – Jon Skeet Dec 12 '20 at 09:01

2 Answers2

1

Check your variable Date interviewDate before the conversion. if it's not a problem, Probally the issue is on method 'convertToLocalDateTime'. Try the simple code below.

public static LocalDateTime convertToLocalDateTime(Date date) {
    return date.toInstant()
               .atZone(ZoneId.systemDefault())
               .toLocalDateTime();  
}
dteodoro
  • 11
  • 2
0

The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API. Learn about the modern date-time API at Trail: Date Time.

Note: For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.

If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

How do I use the modern date-time API if I am getting java.util.Date

Convert the java.util.Date into java.time.Instant using java.util.Date#toInstant. Given below is a demo:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

class Main {
    public static void main(String[] args) throws ParseException {
        // A sample java.util.Date
        Date interviewDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2021-03-05 10:30:00");

        Instant instant = interviewDate.toInstant();

        // Get the local date-time out of instant
        LocalDateTime ldt = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();

        // Now in the local date-time
        LocalDateTime now = LocalDateTime.now();

        // Compare now with ldt
        if (ldt.isAfter(now)) {
            System.out.println("Congratulation! Your interview has been scheduled on " + ldt);
        } else {
            System.out.println("The interview date-time can not be in the past.");
        }
    }
}

Output:

Congratulation! Your interview has been scheduled on 2021-03-05T10:30
Arvind Kumar Avinash
  • 62,771
  • 5
  • 54
  • 92