-1

I want to sort the posts by date("hh:mm:ss"). but I get a mistake. Can you tell me what I did wrong?

java.time.format.DateTimeParseException: Text '12:55:36' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {HourOfAmPm=0, MinuteOfHour=55, SecondOfMinute=36, MicroOfSecond=0, MilliOfSecond=0, NanoOfSecond=0}

class PostX {

    int id;
    String name;
    int score;
    String timePublication;

    public PostX(int id, String name, int score, String timePublication) {
        this.id = id;
        this.name = name;
        this.score = score;
        this.timePublication = timePublication;
    }

    public static void main(String[] args) {

        List<PostX> posts = List.of(
                new PostX(1,"post1", 10, "20:55:36"),
                new PostX(2,"post2", 0, "12:55:36"),
                new PostX(3,"post3", 100, "19:55:36"),
                new PostX(4,"post4", 1000, "23:55:36"),
                new PostX(5,"post5", 10, "01:50:36"),
                new PostX(6,"post6", 3, "20:55:36"),
                new PostX(7,"post7", 4, "20:15:36"),
        );
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm:ss");
        List<PostX> posts1 = posts.stream()
                .sorted(Comparator.comparing(o -> LocalDateTime.parse(o.timePublication, formatter))).limit(5).toList();
    }
}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
R Zav
  • 29
  • 4
  • 1
    Use `LocalTime` or even `Instant` or some other proper date-time typo for your time of publication. Not string. It will make sorting much easier. And you can always format back into a string for presentation. – Ole V.V. May 14 '23 at 11:23
  • 2
    Many similar questions have been posted and answered already. So search. Only in your search skip by any answers using `SimpleDateFormat` and/or `Date` since those classes were troublesome and are now outdated and should not be used any more. – Ole V.V. May 14 '23 at 11:25
  • 1
    You have got two mistakes: (1) Using lower case `hh` for hour of day. Format pattern letters are case sensitive, and you need upper case `HH`. (2) Trying to parse a time of day without a date into a `LocalDateTime`. As the mńame suggests, for a `LocalDateTime` you need both a date and a time of day. A quick solution may be instead to use the `LocalTime` class I mentioned before. – Ole V.V. May 14 '23 at 11:29
  • by the way. it works. But I don't need to sorted(new Comparator<>() { @Override public int compare(PostX o1, PostX o2) { return o2.timePublication.compareTo(o1.timePublication); } }) – R Zav May 14 '23 at 11:30
  • Yes, that should work since the lexicographic ordering of your strings agrees with chronological order. Only you are not getting the validation that you would get from parsing into a `LocalTime`. If someone happens to type `3:34:45` instead of `03:34:45`, a funny ordering will occur that you will have a hard time explaining. Terser: `.sorted(Comparator.comparing(PostX::getTimePublication))` (assuming you are defining that getter). – Ole V.V. May 14 '23 at 11:32
  • 1
    thank you. I replaced hh with HH and LocalDateTime with LocalTime - everything works! – R Zav May 14 '23 at 11:37
  • While I didn’t downvote, the downvotes may be because of lack of demonstrated search and research. On the plus side you have given us expected behaviour, clear error message from your exception and a small and reproducible example, that all helps anyone trying to help you. – Ole V.V. May 14 '23 at 11:53

1 Answers1

0

You need to:

  • change your formatter hours to HH for 24 hour clock.
  • use LocalTime, not LocalDateTime.

To easily display the values, you can override toString() in your class. Here is one possible format.

 @Override
 public String toString() {
     return String.format(
             "PostX [id=%s, name=%s, score=%s, timePublication=%s]", id,
             name, score, timePublication);
 }

Then do the following:


List<PostX> posts1 = posts.stream()
                .sorted(Comparator.comparing(o->LocalTime.parse(o.timePublication, formatter)))
                .limit(5).toList();

posts1.forEach(System.out::println);

prints

PostX [id=5, name=post5, score=10, timePublication=01:50:36]
PostX [id=2, name=post2, score=0, timePublication=12:55:36]
PostX [id=3, name=post3, score=100, timePublication=19:55:36]
PostX [id=7, name=post7, score=4, timePublication=20:15:36]
PostX [id=1, name=post1, score=10, timePublication=20:55:36]
WJS
  • 36,363
  • 4
  • 24
  • 39