Viewed   4.8k times

I am using Java 8 to parse the the date and find difference between two dates.

Here is my snippet:

String date1 ="01-JAN-2017";
String date2 = "02-FEB-2017";

DateTimeFormatter df = DateTimeFormatter .ofPattern("DD-MMM-YYYY", en);
LocalDate  d1 = LocalDate.parse(date1, df);
LocalDate  d2 = LocalDate.parse(date2, df);

Long datediff = ChronoUnit.DAYS.between(d1,d2);

When I run I get the error:

java.time.format.DateTimeParseException: Text could not be parsed at index 3

 Answers

4

The following code works. The problem is you are using "JAN" instead of "Jan". DateTimeFormatter does not recognize that it seems. and also change the pattern to "d-MMM-yyyy".

  String date1 ="01-Jan-2017";
  String date2 = "02-Feb-2017";

  DateTimeFormatter df = DateTimeFormatter.ofPattern("d-MMM-yyyy");
  LocalDate  d1 = LocalDate.parse(date1, df);
  LocalDate  d2 = LocalDate.parse(date2, df);

  Long datediff = ChronoUnit.DAYS.between(d1,d2);  

Source: https://www.mkyong.com/java8/java-8-how-to-convert-string-to-localdate/

Sunday, October 30, 2022
 
2

There is a mismatch in the format for the month and its value in the string. The format is MM which specifies two digits but the value is 9 which is a single digit. You can use single letters for month, day, year, hour, minute, seconds etc. to accommodate all allowable number of digits. Also, I suggest you parse it in a case-insensitive way so that upper and lower case (e.g. AM and am) both can be accommodated.

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Given date-time string
        String dateTimeString = "9/25/2020, 12:46:00 PM";

        DateTimeFormatter dtf = new  DateTimeFormatterBuilder()
                                    .parseCaseInsensitive()
                                    .appendPattern("M/d/u, H:m:s a")
                                    .toFormatter(Locale.ENGLISH);
                                

        // Convert the given date-time string to LocalDateTime
        LocalDateTime ldt = LocalDateTime.parse(dateTimeString, dtf);
        System.out.println(ldt);
        
        //Convert to LocalDateTime Instant if required
        Instant instant=ldt.toInstant(ZoneOffset.UTC);
        System.out.println(instant);
    }
}

Output:

2020-09-25T12:46
2020-09-25T12:46:00Z
Sunday, October 30, 2022
 
3

atZone() does not do what you think it does. It merely attaches a timezone to a date without preserving the instant in time. You must do it using ZonedDateTime#withZoneSameInstant(), which keeps the instant and modifies the zone:

public static void main(String[] args) throws Exception {
    XMLGregorianCalendar xc = DatatypeFactory.newInstance().newXMLGregorianCalendar(2017, 10, 13, 0, 0, 0, 0, 0);
    System.out.println(xc);
    GregorianCalendar gc = xc.toGregorianCalendar();
    System.out.println(gc);
    ZonedDateTime zdt = gc.toZonedDateTime();
    System.out.println(zdt);
    LocalDateTime ldt = zdt.withZoneSameInstant(ZoneId.of("America/Los_Angeles")).toLocalDateTime();
    System.out.println(ldt);
}
Thursday, December 8, 2022
4

Here is a solution using LocalTime that also correctly handles current and closing time being after midnight.

String openHour = "08:00 AM";
String currentHour = "01:00 PM";
String closeHour = "02:00 AM";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "hh:mm a" , Locale.US );
LocalTime openTime = LocalTime.parse(openHour, formatter);
LocalTime currentTime  = LocalTime.parse(currentHour, formatter);
LocalTime closeTime = LocalTime.parse(closeHour, formatter);

boolean isOpen = false;
if (closeTime.isAfter(openTime)) {
  if (openTime.isBefore(currentTime) && closeTime.isAfter(currentTime)) {
    isOpen = true;
  }
} else if (currentTime.isAfter(openTime) || currentTime.isBefore(closeTime)) {
  isOpen = true;
}

if (isOpen) {
  System.out.println("We are open");
} else {
  System.out.println("We are closed");
}
Tuesday, October 11, 2022
 
nautat
 
1

Your date you are trying to parse is not in the right format. The required format you give is yyyy-MM-dd'T'HH:mm:ssX.

This format expects a number for the timezone - even if the number is a zero ('0').

One workaround for this is to create a second SimpleDateFormat that uses a fallback format treating the 'Z' character as a literal and ignoring it. If your first attempt at parsing fails, catch the exception and try parsing with this format - yyyy-MM-dd'T'HH:mm:ss'Z'.

You will also need to override the timezone to force UTC.

Something like:

    try {
        d = input.parse(articleList[5].publishedAt)
    }
    catch (e: ParseException) {
        try {
            val fallback = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
            fallback.timeZone = TimeZone.getTimeZone("UTC")
            d = fallback.parse(articleList[5].publishedAt)
        catch (e2: ParseException) {
            // TODO handle error
        }
    }

Related:

  • simpledateformat parsing date with 'Z' literal
  • Converting ISO 8601-compliant String to java.util.Date
  • how to convert UTC date to locale GMT time on android
Tuesday, September 27, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share