Включение подстановочного знака в SimpleDateFormat - PullRequest
3 голосов
/ 02 марта 2020

Я хочу DateFormatter в java, чтобы я мог указать какой-то специальный символ, а также цифры в выражении даты. Например:

String dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";

Здесь dd используется для указания дня месяца, который равен цифре c. Но у меня есть требование создать дату, как показано ниже:

 String stringDate = "2017-12-??T00:00Z";
 SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
 formatter.parse(stringDate);

Я получаю необъяснимое исключение, так как ДЕНЬ, указанный здесь ?? , Есть ли обходной путь для этого или мне нужно написать новый парсер?

Спасибо

Ответы [ 2 ]

4 голосов
/ 02 марта 2020

Попробуйте экранировать дополнительные литералы, используя одинарные кавычки

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-'??T'HH:mm:ss.SSS zzz");

Также значение и формат должны соответствовать (может редактировать строковую дату по мере необходимости), в вашем случае будет работать следующий синтаксис.

String stringDate = "2017-12-??T00:00Z";
Date date = (new SimpleDateFormat("yyyy-MM-'??T'HH:mmZ")).parse(stringDate.replaceAll("Z$", "+0000"));
System.out.println("date: " + (new SimpleDateFormat("yyyy-MM-dd'??T'HH:mmZ")).format(date));

Обратите внимание, что «Z» означает, что часовой пояс также соответствует стандарту часового пояса РФ C 822.

1 голос
/ 02 марта 2020

Редактировать: Рассмотрим планировщик. Ваш комментарий может звучать так, как будто вам нужен планировщик, например, кварцевый планировщик. Я включаю ссылку внизу. Затем преобразуйте пользовательский ввод не в YearMonth, OffsetDateTime или любой другой объект даты и времени (потому что они не подходят), а в синтаксис, который может принять ваш планировщик.

Оригинал ответ

Я даю вам пару советов. Хотя с оговоркой: я не понимаю, почему вы этого хотите, даже не совсем то, что вы хотите, поэтому эти предложения могут быть не для вас.

Одно предложение, в котором я почти уверен: Для работы с датой и временем используйте java .time, современный java API даты и времени. Работать с ней намного приятнее, чем со старыми, плохо спроектированными и давно устаревшими классами даты и времени, которые включают в себя печально известный SimpleDateFormat класс.

Анализ года и месяца: Если вы просто выберите год и месяц из строки, в которой вместо дня месяца есть вопросительные знаки, проанализируйте YearMonth:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-'??T'HH:mmX");

    String stringDate = "2017-12-??T00:00Z";
    YearMonth ym = YearMonth.parse(stringDate, formatter);
    System.out.println("Year and month are " + ym);

Выходные данные этого фрагмента:

Year and month are 2017-12

Разбор всей информации из строки: Если вам нужно время суток и смещение от той же строки, просто проанализируйте строку один раз и получите различную информацию из результата разбора:

    TemporalAccessor parsed = formatter.parse(stringDate);
    YearMonth ym = YearMonth.from(parsed);
    System.out.println("Year and month are " + ym);
    LocalTime time = LocalTime.from(parsed);
    System.out.println("Time of day is " + time);
    ZoneOffset offset = ZoneOffset.from(parsed);
    System.out.println("UTC offset is " + offset);
Year and month are 2017-12
Time of day is 00:00
UTC offset is Z

Использование дня месяца по умолчанию: Если вы знаете, какой день месяца вы хотите использовать вместо вопросительных знаков, укажите его как значение по умолчанию:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-'??T'HH:mmX")
            .parseDefaulting(ChronoField.DAY_OF_MONTH, 23)
            .toFormatter();
    String stringDate = "2017-12-??T00:00Z";
    OffsetDateTime dateTime = OffsetDateTime.parse(stringDate, formatter);
    System.out.println("Date and time is " + dateTime);
Date and time is 2017-12-23T00:00Z

Принятие как цифр, так и знаков вопроса: Если дата может быть задана либо цифрами c, либо знаками вопроса, использовать необязательные части в строках шаблона формата , Они заключены в квадратные скобки:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-[??][dd]'T'HH:mmX")
            .parseDefaulting(ChronoField.DAY_OF_MONTH, 23)
            .toFormatter();
    String stringDate = "2017-12-??T00:00Z";
    OffsetDateTime dateTime = OffsetDateTime.parse(stringDate, formatter);
    System.out.println("Date and time is " + dateTime);
    stringDate = "2018-02-16T00:00Z";
    dateTime = OffsetDateTime.parse(stringDate, formatter);
    System.out.println("Date and time is " + dateTime);
Date and time is 2017-12-23T00:00Z
Date and time is 2018-02-16T00:00Z

Учебные ссылки

...