my goal is create a method that parse dates from Strings, both string and pattern are given as parameters, but some of the date strings does not contain any time values, so in my method i set default time values to current time values stored in variable 'now', but i am having some troubles parsing dates like this 10 may 2020 7:15 am
. the code i use to parse the dates looks like this
@Test
public void patronFechaZDT(){
String strFecha = "10 may 2020 7:15 am";
ZonedDateTime now = ZonedDateTime.now();
DateTimeFormatter dtf1 = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("dd MMMM yyyy h:mm a")
.parseDefaulting(ChronoField.HOUR_OF_DAY, now.getHour())
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, now.getMinute())
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, now.getSecond())
.toFormatter(Locale.US)
.withZone(ZoneId.systemDefault());
TemporalAccessor accessor = dtf1.parse(strFecha, new ParsePosition(0));
ZonedDateTime fecha = ZonedDateTime.from(accessor);
System.out.println("str: " + strFecha + ", fecha: " + fecha );
}
The output of the code above is
java.time.format.DateTimeParseException: Text '10 may 2020 7:15 am' could not be parsed: Conflict found: HourOfDay 16 differs from HourOfDay 7 while resolving AmPmOfDay
I alrready noticed the problem is the default value 'HOUR_OF_DAY' which causes conflict with the hour captured in the string, and removing the line .parseDefaulting(ChronoField.HOUR_OF_DAY, now.getHour())
, my code runs well
The main problem is that my method will recive a lot of patterns and strings, and some of this patterns will not contain time values, or zone values, and i really want to parse the dates using default time values, so if it is posile i want to keep the line .parseDefaulting(ChronoField.HOUR_OF_DAY, now.getHour())
, thanks in advance.
Edit
As @akuzminykh sugested, i add the correct ChronoField CLOCK_HOUR_OF_AMPM
and my DateTimeFormatter now looks like this:
int hour = now.getHour(); int am = 0;
if(hour > 12){
hour = hour - 12;
am = 1;
}
DateTimeFormatter dtf1 = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("dd MMMM yyyy hh:mm a")
.parseDefaulting(ChronoField.AMPM_OF_DAY, am)
.parseDefaulting(ChronoField.CLOCK_HOUR_OF_AMPM, hour)
.parseDefaulting(ChronoField.HOUR_OF_DAY, now.getHour())
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, now.getMinute())
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, now.getSecond())
.toFormatter(Locale.US)
.withZone(ZoneId.systemDefault());
But, unless i coment the line .parseDefaulting(ChronoField.HOUR_OF_DAY...
this new Formatter produces the same exception. Any help willl be apreciated
When you parse h
, which is for clock-hour-of-am-pm (1-12) (see DateTimeFormatter
), you of course have to use the correct ChronoField
for your parseDefaulting
. Check out ChronoField
. What you need is ChronoField.CLOCK_HOUR_OF_AMPM
.