2

Here's my code:

private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd HH:mm:ss");

LocalDateTime timeStamp = LocalDateTime.parse(string, formatter);

Which results in the follwoing exception:

java.time.format.DateTimeParseException: Text 'Oct 10 13:10:01' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MonthOfYear=10, DayOfMonth=10},ISO resolved to 13:10:01 of type java.time.format.Parsed

Using Java 1.8.0_31.

I did look around and found many similar issues but non of them matches this one exatcly and solutions offered there are not applicable here:

Here the reason for the same issue was using LocalDateTime without the Time parts. As you can see from the expection this is not the case here.

I'm not using week-based year as in this example.

And finally unlike here I'm using LocalDateTime so timezones should not be a problem. But as it's supposedly a bug in DateTimeFormatter I've tried to pass the formatter as 'formatter.withZone(ZoneId.systemDefault())' (suggested workaround) which resulted in the same exception.

Community
  • 1
  • 1
thisismydesign
  • 21,553
  • 9
  • 123
  • 126
  • 1
    My guess is, that this is caused by the missing year in the value and the pattern. –  Oct 11 '16 at 14:00
  • @a_horse_with_no_name this is indeed the case (nevermind my previous comment, I had used `YYYY` instead of `yyyy`) ; see [this ideone](https://ideone.com/4iS6Ty) – Aaron Oct 11 '16 at 14:06
  • Yep thanks. @a_horse_with_no_name I will accept if you post this as an answer. – thisismydesign Oct 11 '16 at 14:08
  • I have discussed the theory behind `java.time` at length here: https://stackoverflow.com/a/56508200/145989 – Ondra Žižka Jun 08 '19 at 17:58

2 Answers2

3

A LocalDateTime needs a year - otherwise the formatter has no way to decide whether that 10th of October should be in 2016 or in 452 BC.

You can add a default behaviour to a DateTimeFormatter, for example with:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern("MMM dd HH:mm:ss")
        .parseDefaulting(ChronoField.YEAR_OF_ERA, 2016)
        .toFormatter(Locale.ENGLISH);

Or make it a bit more flexible to default to the current year with:

        .parseDefaulting(ChronoField.YEAR_OF_ERA, Year.now().getValue())
assylias
  • 321,522
  • 82
  • 660
  • 783
1

The Answer by assylias is correct, and should be accepted.

MonthDay

If you did indeed want a value of only a month and a day-of-month without any year, such as a recurring anniversary/birthday, then use the MonthDay class.

To parse a string into a MonthDay, call MonthDay.parse and pass a DateTimeFormatter matching your String input format.

DateTimeFormatter f = 
    DateTimeFormatter.ofPattern( "MMM dd HH:mm:ss" )
                     .withLocale( Locale.ENGLISH );
MonthDay md = MonthDay.parse( "Oct 10 13:10:01" , f );

Similarly, you can represent the time-of-day with the LocalTime class. Search Stack Overflow for countless examples.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154