java DateTimeFormatterBuilder fails on testtime [duplicate]
Asked Answered
T

2

2

I have a simple jUnit test for DateTimeFormatterBuilder. At runtime it works, when some String comes on Spring-MVC hanlder (@RequestParam)

At testtime it fails with the same String value.

Tested value: 25-May-2018 11:10

Method to be tested:

public void getTimeDifference(@RequestParam String startDate, @RequestParam String endDate) {
    DateTimeFormatter DATE_TIME_FORMAT = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("dd-MMM-yyyy HH:mm").toFormatter();
    LocalDateTime.parse(startDate,DATE_TIME_FORMAT);
    return   messages;
}

Test-Method:

@Test
public void testFormat() throws Exception {
    final String startDateFormatA = "25-May-2018 11:10";
    final String endDateFormatA = "25-May-2018 11:10";
    assertEquals("06:00", callDbController.getTimeDifference(startDateFormatA, endDateFormatA)[1]);
}

My Test: At runtime I set a break-point and test it on Display-View:

LocalDateTime.parse("25-May-2018 11:10",DATE_TIME_FORMAT)

At testtime with the same spring-aplication-context I do the same like on runtime and it fails.

Does anyboby have ideas?

Tribal answered 25/5, 2018 at 9:46 Comment(4)
You say "it fails", but don't tell us the exception details. Message? Stack trace? Anything?Idioglossia
Apart from your issue, why are you not directly parsing into the Instant? Do you really know what an Instant is? Its the time in UTC. Instant result = formatter.parse(lo.time, Instant::from);.Treadwell
Is your locale US? If not, the expected month names may be localized and not match the english ones.Treadwell
See How to parse month full form string using DateFormat in Java? for the locale issue.Treadwell
O
3

The month name is in English, so you'd better set a java.util.Locale in the formatter.

If you don't set it, the formatter will use the JVM default locale. And if it's not English, you might get an error (and different environments might have different configurations, so it's better to set the locale instead of relying on the JVM's default).

Just do toFormatter(Locale.ENGLISH) instead of just toFormatter() and that's it.

Organometallic answered 25/5, 2018 at 11:0 Comment(0)
R
2

You are using hh which is clock-hour-of-am-pm (1-12) without adding the AM/PM information in the date string.

Instead you should use of hour-of-day (0-23) like the pattern: DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z");

Or you can add the a in the date pattern:
DateTimeFormatter.ofPattern("dd/MMM/yyyy:hh:mm:ss a Z");

and pass the AM/PM information in the date string:

"20/Mar/2019:00:00:01 AM +0100"


EDIT:

As per the comments, the issue could also be with the locale you are using, in order to use the en/US locale just pass the locale to the ofPattern method:

 Locale locale = new Locale("en", "US");
 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z", locale); 

But you still need to correct the clock-hour-of-am-pm (hh) to hour-of-day (HH).

Runkel answered 31/3, 2019 at 9:40 Comment(6)
For the OP input, this throws the same exception.Teledu
@Glains, No I have checked if you change the pattern to dd/MMM/yyyy:HH:mm:ss Z I am getting a valid instant with the input OP is providing.Runkel
The issue might be about OPs locale not being US. And then Mar is invalid, since its expecting the localized month name. Setting the locale or providing the correct localized month name would fix it then.Treadwell
@Zabuza I think you are right, I tested with another locale (es/ES) then I was able to reproduce OP's error. So mentioning the locale to en/US fixed it.Runkel
@Zabuza Thanks, you were right. I had to set locale to US to make it workMarkova
answer was merged from https://mcmap.net/q/753383/-java-datetimeformatterbuilder-fails-on-testtime-duplicate, please edit the answer to suit this question, then flag this comment as "no longer needed"Reinhardt

© 2022 - 2024 — McMap. All rights reserved.