Как преобразовать формат даты «yyyyMMdd» в простой формат даты «ccyyMMdd» в java

Я хочу преобразовать формат из «yyyyMMdd» в «ccyyMMdd» simpledateformat в java. Я получаю «c» как недопустимый символ в java. Пожалуйста, помогите мне найти решение для преобразования в формат "ccyyMMdd" в java Simpledateformat

В чем разница между «cc» и «yy» в java?

stackoverflow.com/questions/33420395/…
Simon B 15.04.2019 09:21

Что вы ожидали получить от «cc»?

Ivar 15.04.2019 09:26
stackoverflow.com/questions/6229347/…
vlad324 15.04.2019 09:26

Кстати, вы должны прекратить использовать SimpleDateFormat и начать использовать новый Java Date and Time API (в пакете java.time).

MC Emperor 15.04.2019 10:07

Я рекомендую вам не использовать SimpleDateFormat. Этот класс и его друзья, такие как Date, плохо спроектированы и давно устарели (сам SimpleDateFormat, как известно, доставляет много хлопот). Вместо этого используйте DateTimeFormatter и другие классы из java.time, современный API даты и времени Java.

Ole V.V. 15.04.2019 10:21

К вашему сведению, ужасно проблемные классы даты и времени, такие как java.util.Date, java.util.Calendar и java.text.SimpleDateFormat, теперь являются наследие, вытесненными классами Java.время, встроенными в Java 8 и более поздние версии. См. Руководство от Oracle.

Basil Bourque 15.04.2019 23:35

Всегда ищите Stack Overflow перед публикацией.

Basil Bourque 15.04.2019 23:35
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
7
4 314
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

cc означает век.

Невозможно преобразовать yyMMdd в ccyyMMdd, так как у вас нет полного года в исходной дате. Например, дата 190415 может быть как в 21 веке, так и в 20 веке.

Имея дату, подобную 190515 разбору с yyMMdd, вы получите год 2019...

AxelH 15.04.2019 09:58

Наличие даты типа 800415 даст вам 1980, потому что простой синтаксический анализатор формата даты построен таким образом, но строка 800415 может представлять дату 20800415 и 19800415 и т. д.

vlad324 15.04.2019 10:10

Согласен, но не бывает даты без контекста "века". В строке из двух цифр полный год будет основан на текущем году. currentYear - 80 < value < currentYear + 20. С сегодняшнего дня вы можете записаться на свидание в 16/04/1939 < value < 15/04/2039

AxelH 15.04.2019 10:22

Согласен, но контекст этого века создан условно, поэтому совпадения 1 к 1 для таких дат у нас нет.

vlad324 15.04.2019 11:10
Ответ принят как подходящий

SimpleDateFormat не поддерживает c для Century. Но если вам просто нужен четырехзначный год, вы можете использовать yyyy

Вы можете найти полный список поддерживаемых в официальном документе SimpleDateFormat.

//import java.util.Date;
//import java.text.SimpleDateFormat;

String s = "190415";
SimpleDateFormat sdfIn = new SimpleDateFormat("yyMMdd");
SimpleDateFormat sdfout = new SimpleDateFormat("yyyyMMdd");

Date d = sdfIn.parse(s);
System.out.println("OLD : " + sdfout.format(d));

OLD : 20190415

Как уже говорилось, вам также следует переключиться на новый API даты/времени Java, но вы обнаружите ту же проблему, DateTimeFormatter не имеет функции «века».

//import java.time.LocalDate;
//import java.time.format.DateTimeFormatter;

String s = "190415";
DateTimeFormatter dtfIn = DateTimeFormatter.ofPattern("yyMMdd");
DateTimeFormatter dtfOut = DateTimeFormatter.ofPattern("yyyyMMdd");

LocalDate ld = LocalDate.parse(s, dtfIn);
System.out.println("NEW : " + dtfOut.format(ld));

NEW : 20190415

Как и другие, я предполагаю, что cc на век. Итак, ccyy это то же самое, что и yyyy. Существуют средства форматирования для других языков, кроме Java, которые принимают cc или CC для века.

Обновлено: преобразование не требуется

Поскольку ccyy означает yyyy, преобразование yyyyMMdd в ccyyMMdd не требуется. Строка, которую вы уже получили в формате yyyyMMdd, также является строкой, которую вы хотите.

Оригинальный ответ

Изначально вы просили преобразовать yyMMdd в ccyyMMdd. Например, сегодняшняя дата будет преобразована из 190415 в 20190415.

Чтобы сделать это преобразование правильно, вам нужно знать, какой век имеется в виду. Если дата продажи билетов на концерт, вы, вероятно, можете с уверенностью предположить, что этот год находится в пределах следующих 20 лет (включая текущий год). Если это день рождения живого человека, вы уже облажались, извините, потому что это может быть в последние 110 или более лет, поэтому вы не можете знать, означает ли 150415 год 1915 или 2015, век 19 или 20. В любом случае, Я рекомендую вам выбрать диапазон допустимых дат, лучше всего несколько уже, чем 100 лет, чтобы у вас была некоторая проверка и возможность определить, не нарушает ли какая-либо дата ваши предположения.

Java.время

Для примера предположим, что дата находится в пределах последних 30 или ближайших 5 лет (это позволяет нам получить век 19 или 20 в зависимости от года).

    // The base year just needs to be before the minimum year
    // and at most 99 years before the maximum year
    int baseYear = Year.now().minusYears(40).getValue();

    DateTimeFormatter originalDateFormatter = new DateTimeFormatterBuilder()
            .appendValueReduced(ChronoField.YEAR, 2, 2, baseYear)
            .appendPattern("MMdd")
            .toFormatter();
    
    String originalDateString = "921126";
    LocalDate today = LocalDate.now(ZoneId.of("Africa/Bangui"));
    LocalDate date = LocalDate.parse(originalDateString, originalDateFormatter);
    if (date.isBefore(today.minusYears(30)) || date.isAfter(today.plusYears(5))) {
        System.out.println("Date " + originalDateString + " is out of range");
    } else {
        String ccyymmddDateString = date.format(DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println("String " + originalDateString + " was reformatted to " + ccyymmddDateString);
    }

Вывод при запуске сегодня:

String 921126 was reformatted to 19921126

Некоторые другие исходные строки дают:

String 200430 was reformatted to 20200430

Date 240430 is out of range

Формат, который вы хотите, yyyyMMdd, согласуется со встроенным форматом BASIC_ISO_DATE, поэтому я просто использую его для форматирования даты.

Я рекомендую вам не использовать SimpleDateFormat. Этот класс, как известно, доставляет много хлопот и, к счастью, давно устарел. Также SimpleDateFormat не позволяет вам контролировать интерпретацию двузначного года так, как я это делаю выше. Вместо этого я использую DateTimeFormatter и другие классы из java.time, современного API даты и времени Java.

Связь:Учебное пособие по Oracle: дата и время объясняет, как использовать java.time.

Другие вопросы по теме