-2

When I run this I get exception: Exception in thread "main" java.time.format.DateTimeParseException: Text '2020-12-15 13:48:52' could not be parsed: Invalid value for ClockHourOfAmPm (valid values

I write to console: 2020-12-15 13:48:52

public class Main {
    public static void main(String[] args) {


        Scanner scanner = new Scanner(System.in);
        System.out.println("Podaj datę:");
        String input = scanner.nextLine();


        if (input.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
            DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
            LocalDateTime localDateTime = LocalDateTime.parse(input, dateTimeFormatter1);
            printDateTime(localDateTime);
        } else if (input.matches("\\d{2}.\\d{2}.\\d{4} \\d{2}:\\d{2}:\\d{2}")) {
            DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("dd.MM.yyyy hh:mm:ss");
            LocalDateTime localDateTime2 = LocalDateTime.parse(input, dateTimeFormatter2);
            printDateTime(localDateTime2);
        } else if (input.matches("\\d{4}-\\d{2}-\\d{2}")) {
            DateTimeFormatter dateTimeFormatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDateTime localDateTime3 = LocalDateTime.parse(input, dateTimeFormatter3);
            printDateTime(localDateTime3);
        } else {
            System.out.println("Zły format");
        }
    }

    private static void printDateTime(LocalDateTime localDateTime) {
        System.out.println("Czas lokalny: " + ZonedDateTime.now());
        System.out.println("UTC: " + ZonedDateTime.of(localDateTime, ZoneId.of("UTC")));
        System.out.println("Londyn: " + ZonedDateTime.of(localDateTime, ZoneId.of("London")));
        System.out.println("Los Angeles: " + ZonedDateTime.of(localDateTime, ZoneId.of("Los Angeles")));
        System.out.println("Sydney: " + ZonedDateTime.of(localDateTime, ZoneId.of("Sydney")));
    }
}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • 1
    Use HH instead of hh. Also, London is not a valid ZondId – Matthew S. Feb 25 '21 at 20:18
  • Alternatively: `LocalDateTime.parse( "2020-12-15 13:48:52".replace( " " , "T" ) )` Replace the SPACE in middle with a `T` to comply with standard ISO 8601 formats used by default in *java.time*. – Basil Bourque Feb 25 '21 at 21:39

2 Answers2

2

For this requirement, do not use regex because it makes your program unnecessarily complex and error-prone. You can use the optional patterns in square brackets with DateTimeFormatter. Apart from this,

  1. Use DateTimeFormatterBuilder#parseDefaulting to append a default value for a field (e.g. HOUR_OF_DAY) to the formatter for use in parsing.
  2. Use ZonedDateTime#withZoneSameInstant to return a copy of this date-time with a different time-zone, retaining the instant.
  3. Use the standard naming convention (Region/City) of timezone e.g. Europe/London.
  4. Use HH instead of hh for HOUR_OF_DAY (i.e. time in 24-hour format). The symbol, hh is used with a which specifies am/pm (i.e. time in 12-hour format).

Demo:

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                .appendPattern("[uuuu-MM-dd HH:mm:ss][dd.MM.uuuu HH:mm:ss][uuuu-MM-dd]")
                .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
                .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
                .toFormatter(Locale.ENGLISH);

        System.out.print("Podaj datę:");
        String input = scanner.nextLine();
        LocalDateTime localDateTime = LocalDateTime.parse(input, dtf);
        System.out.println(localDateTime);

        printDateTime(LocalDateTime.parse(input, dtf));
    }

    private static void printDateTime(LocalDateTime localDateTime) {
        // Default timezone
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdtDefaultTimeZone = localDateTime.atZone(zoneId);

        System.out
                .println("Date-time at " + zoneId + ": " + zdtDefaultTimeZone);
        System.out.println("At UTC: " + zdtDefaultTimeZone.withZoneSameInstant(ZoneId.of("Etc/UTC")));
        System.out.println("In London: " + zdtDefaultTimeZone.withZoneSameInstant(ZoneId.of("Europe/London")));
        System.out
                .println("In Los Angeles: " + zdtDefaultTimeZone.withZoneSameInstant(ZoneId.of("America/Los_Angeles")));
        System.out.println("In Sydney: " + zdtDefaultTimeZone.withZoneSameInstant(ZoneId.of("Australia/Sydney")));
    }
}

A sample run:

Podaj datę:2020-02-23 10:15:20
2020-02-23T10:15:20
Date-time at Europe/London: 2020-02-23T10:15:20Z[Europe/London]
At UTC: 2020-02-23T10:15:20Z[Etc/UTC]
In London: 2020-02-23T10:15:20Z[Europe/London]
In Los Angeles: 2020-02-23T02:15:20-08:00[America/Los_Angeles]
In Sydney: 2020-02-23T21:15:20+11:00[Australia/Sydney]

Another sample run:

Podaj datę:23.02.2020 10:15:20
2020-02-23T10:15:20
Date-time at Europe/London: 2020-02-23T10:15:20Z[Europe/London]
At UTC: 2020-02-23T10:15:20Z[Etc/UTC]
In London: 2020-02-23T10:15:20Z[Europe/London]
In Los Angeles: 2020-02-23T02:15:20-08:00[America/Los_Angeles]
In Sydney: 2020-02-23T21:15:20+11:00[Australia/Sydney]

Another sample run:

Podaj datę:2020-02-23
2020-02-23T00:00
Date-time at Europe/London: 2020-02-23T00:00Z[Europe/London]
At UTC: 2020-02-23T00:00Z[Etc/UTC]
In London: 2020-02-23T00:00Z[Europe/London]
In Los Angeles: 2020-02-22T16:00-08:00[America/Los_Angeles]
In Sydney: 2020-02-23T11:00+11:00[Australia/Sydney]

Learn more about the modern date-time API from Trail: Date Time.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
1

Your DateTime pattern in your DateTimeFormatter causes the problem you see here. You need to use HH instead of hh

  • hh: This is an hour-of-day pattern that uses a 12 hour clock, with AM/PM indications.
  • HH: This is an hour-of-day pattern that uses a 24 hour clock. Takes input between 0-23

Sidenote, the zones you use seem to be invalid. The corresponding zones would be

Europe/London
America/Los_Angeles
Australia/Sydney
Yoni
  • 1,370
  • 7
  • 17