ZonedDateTime.parse не работает в течение времени анализа с утра или вечера - PullRequest
2 голосов
/ 09 апреля 2020

Я учусь java, пытаюсь создать инструмент для преобразования заданного c времени из часового пояса A в часовой пояс B на основе пользовательского ввода (ввод времени, часового пояса A и часового пояса B). Речь идет о той части, где инструмент собирает время в определенном формате c, чтобы преобразовать его в объект ZonedDateTime.

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public static String fullTime;
public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm a");
public static ZonedDateTime newTime;

public static void getHourAndMinutes(){
        System.out.print("Please type in the time you have in mind in format hh:mm am/pm\n");
        Scanner in = new Scanner(System.in);
        fullTime = in.nextLine();
        System.out.println(fullTime);
        newTime = ZonedDateTime.parse(fullTime, formatter);

Я попытался ввести время в таких форматах, как 22:30, 10 : 30:00, 22:30, 22:30, 10: 30, 10:30, все эти записи вызвали ошибку исключения, я получаю ошибки, подобные этой

Exception in thread "main" java.time.format.DateTimeParseException: Text '10:30 pm' could not be parsed at index 6

Есть идеи, что я могу делать не так? Спасибо!

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

Поскольку пользователь, вводящий ввод, просто представляет время, вам нужно проанализировать его в LocalTime , а другая ошибка заключается в том, что вы используете неправильный шаблон, H - это час дня (0- 23); вам нужно h в DateTimeFormatter

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a");

LocalTime localTime = LocalTime.parse("10:30 PM",formatter);

После анализа ввода в LocalTime вы можете преобразовать его в ZonedDateTime . Но вы должны указать дату (LocalDate), а также время и зону. Ваш код в Вопросе имел только время суток, и ему не хватало даты и зоны, необходимых для создания экземпляра ZonedDateTime.

ZonedDateTime dateTime = localTime.atDate(LocalDate.now()).atZone(ZoneId.systemDefault());

И затем вы можете преобразовать его в другую зону, используя withZoneSameInstant

ZonedDateTime result = dateTime.withZoneSameInstant(ZoneId.of("America/New_York));
1 голос
/ 11 апреля 2020

Есть идеи, что я могу делать не так? Спасибо!

Боюсь нескольких вещей.

  1. Для ZonedDateTime вам нужны дата, время и часовой пояс. Для разбора строки, содержащей только время дня, в ZonedDateTime вам потребуется указать дату по умолчанию и часовой пояс по умолчанию. Однако вместо этого я бы проанализировал LocalTime, который является точным временем, если день без даты и без часового пояса. После разбора вы можете конвертировать. Вам необходимо выбрать дату конверсии, поскольку ваш часовой пояс A (и B тоже), вероятно, использует другое смещение UT C в разные даты из-за летнего времени (DST) и / или истории c и / или будущих изменений в их базовом смещении UT C.
  2. Вам необходимо указать локаль для вашего средства форматирования, чтобы сказать, на каком языке предполагать AM и PM. Например, DateTimeFormatter.ofPattern("HH:mm a", Locale.ENGLISH).
  3. Необходимо ввести AM или PM в правильном регистре (верхний или нижний регистр) для указанной локали.
  4. Для анализа строки с часом в пределах AM или PM с 01 по 12 необходимо использовать строчные буквы hh в строке шаблона формата. Не верхний регистр HH, который будет для часа дня с 00 до 23.
...