Синтаксический анализ строки по дате с другим форматом в Java

93

Я хочу , чтобы преобразовать Stringв Dateв различных форматах.

Например,

Я получаю от пользователя,

String fromDate = "19/05/2009"; // i.e. (dd/MM/yyyy) format

Я хочу преобразовать это fromDateкак объект Date "yyyy-MM-dd"формата

Как я могу это сделать?

Гнанияр Зубаир
источник
2
Объект Date не имеет формата, это просто число, представляющее дату. Дата может быть представлена ​​строкой в ​​формате «гггг-ММ-дд».
user85421

Ответы:

182

Взгляните на SimpleDateFormat. Код выглядит примерно так:

SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

try {

    String reformattedStr = myFormat.format(fromUser.parse(inputString));
} catch (ParseException e) {
    e.printStackTrace();
}
Майкл Майерс
источник
1
Могу ли я получить вывод в Dateформате вместо строкового формата?
Рэйчел
4
@ Рэйчел: Конечно, просто используйте parseи не продолжайте format. parseанализирует строку на дату.
Майкл Майерс
3
Но parseдает мне , date formatкак , Fri Jan 06 00:01:00 EST 2012но это нужно в 2012-01-06формате дата
Рахиль
1
@Rachel это потому, что когда вы вызываете System.out.println(anyDateObject)метод toString () по умолчанию, который, как было сказано, печатает в этом формате, например Fri Jan 06 00:01:00 EST 2012. Вам нужно переопределить его в соответствии со своими потребностями.
KNU
3
FYI, хлопотно старые классы даты и времени , такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormatтеперь наследие , вытесняется java.time классов , встроенных в Java 8 и Java 9. См руководство по Oracle .
Basil Bourque
14

tl; dr

LocalDate.parse( 
    "19/05/2009" , 
    DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) 
)

Детали

Другие ответы с java.util.Date, java.sql.Dateи SimpleDateFormatв настоящее время устарели.

LocalDate

Современный способ установить дату и время - это, в частности, работать с классами java.time LocalDate. LocalDateКласс представляет собой дату только значение без времени суток и без временной зоны.

DateTimeFormatter

Чтобы проанализировать или сгенерировать String, представляющий значение даты и времени, используйте DateTimeFormatterкласс.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = LocalDate.parse( "19/05/2009" , f );

Не объединяйте объект даты и времени со строкой, представляющей его значение. Объект даты и времени не имеет формата , в отличие от String. Объект даты и времени, например LocalDate, может генерировать String для представления своего внутреннего значения, но объект даты и времени и String являются отдельными отдельными объектами.

Вы можете указать любой настраиваемый формат для создания строки. Или позвольте java.time выполнить автоматическую локализацию.

DateTimeFormatter f = 
    DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL )
                     .withLocale( Locale.CANADA_FRENCH ) ;
String output = ld.format( f );

Выгрузить в консоль.

System.out.println( "ld: " + ld + " | output: " + output );

ld: 2009-05-19 | вывод: mardi 19 mai 2009

Посмотрите в действии на IdeOne.com .


О java.time

Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как java.util.Date, Calendar, и SimpleDateFormat.

Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial . И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310 .

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в java.sql.*занятиях.

Где взять классы java.time?

  • Java SE 8 , Java SE 9 и более поздние версии
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • В Java 9 добавлены некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP… .

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval, YearWeek, YearQuarter, и более .

Василий Бурк
источник
12

Используйте SimpleDateFormatкласс:

private Date parseDate(String date, String format) throws ParseException
{
    SimpleDateFormat formatter = new SimpleDateFormat(format);
    return formatter.parse(date);
}

Применение:

Date date = parseDate("19/05/2009", "dd/MM/yyyy");

Для эффективности вы можете хранить свои средства форматирования в хэш-карте. Хэш-карта является статическим членом вашего класса util.

private static Map<String, SimpleDateFormat> hashFormatters = new HashMap<String, SimpleDateFormat>();

public static Date parseDate(String date, String format) throws ParseException
{
    SimpleDateFormat formatter = hashFormatters.get(format);

    if (formatter == null)
    {
        formatter = new SimpleDateFormat(format);
        hashFormatters.put(format, formatter);
    }

    return formatter.parse(date);
}
Агора
источник
9
ПРЕДОСТЕРЕЖЕНИЕ!! Идея хорошая, а вот реализация - нет. DateFormats не должны храниться статически, потому что они не являются потокобезопасными! Если они используются более чем из одного потока (а это всегда рискованно для статики). FindBugs содержит детектор для этого (который я использовал изначально, после того, как меня укусили. См. Dschneller.blogspot.com/2007/04/… :-))
Daniel Schneller
Вашу запись в блоге интересно читать :-) Что делать, если сам parseDate-метод я синхронизировал? Проблема, однако, в том, что это, вероятно, замедлит код ...
Агора
1
Пока метод parseDate был единственным методом доступа к карте, его синхронизация работала. Однако это, как вы говорите, создало бы узкое место.
Дэниел Шнеллер
8

Преобразование строковой даты в java.sql.Date

String fromDate = "19/05/2009";
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date dtt = df.parse(fromDate);
java.sql.Date ds = new java.sql.Date(dtt.getTime());
System.out.println(ds);//Mon Jul 05 00:00:00 IST 2010
Ритеш Кошик
источник
3

Хотя SimpleDateFormatэто действительно сработает для ваших нужд, вы также можете попробовать Joda Time , который, по-видимому, является основой для переделанной библиотеки Date в Java 7. Хотя я не использовал ее часто, я слышал только хорошие вещи об этом, и если вы активно манипулируете датами в своих проектах, возможно, стоит изучить это.

Джеймс МакМахон
источник
2

Предположим, у вас есть такая строка:

String mDate="2019-09-17T10:56:07.827088"

Теперь мы хотим изменить этот Stringформат отдельно для даты и времени в Java и Kotlin .

ЯВА:

у нас есть метод извлечения даты :

public String getDate() {
    try {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mDate);
        dateFormat = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
        return dateFormat.format(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

Return это: 17.09.2019

И у нас есть метод извлечения времени :

public String getTime() {

    try {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mCreatedAt);
        dateFormat = new SimpleDateFormat("h:mm a", Locale.US);
        return dateFormat.format(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

Returnэто: 10:56 AM

КОТЛИН:

у нас есть функция для извлечения даты :

fun getDate(): String? {

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val date = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("MM/dd/yyyy", Locale.US)
    return dateFormat.format(date!!)
}

Return это: 17.09.2019

И у нас есть метод извлечения времени :

fun getTime(): String {

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val time = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("h:mm a", Locale.US)
    return dateFormat.format(time!!)
}

Returnэто: 10:56 AM

Милад Салими
источник
Пожалуйста, не учите молодых пользоваться давно устаревшим и заведомо неприятным SimpleDateFormatуроком. По крайней мере, не в качестве первого варианта. И не без оговорок. Сегодня у нас есть намного лучше java.time, современный API даты и времени Java и его DateTimeFormatter. Также SimpleDateFormatне может правильно анализировать 6 десятичных знаков в секундах (микросекундах).
Ole VV
Когда я запускаю ваш второй фрагмент, я получаю не то, 10:56 AMчто вы говорите, а вместо этого 11:09 AM(проверено на Oracle jdk-11.0.3).
Ole VV
@ OleV.V. , Если метод давно устарел, он будет считаться устаревшим со строчкой в ​​качестве знака, если метод или класс не являются устаревшими, мы можем его использовать, я не говорю, что это лучший способ, может быть, у нас есть лучший способ, но этот способ просто и понятно, если метод или класс были старыми, нет причин, по которым это неудобно, а для использования DateTimeFormatterнам нужно minsdk 26или выше, то это нехорошо,
milad salimi
@ OleV.V. Но спасибо за ваш комментарий и по поводу вашего второго комментария, я могу сказать, что я проверял его много раз в двух приложениях, и он возвращается10:56 AM
Милад Салими
1
@ OleV.V. , Хорошо, но я использую библиотеку, когда у меня нет возможности, или этот API (библиотека) намного лучше, чем мой код, потому что, когда вы добавляете библиотеку, вы добавляете некоторые коды в свой проект, которые могут не использоваться, и это перегрузка для вашего проект, это мой подход, и ваш подход мне нравится.
milad salimi
1

Простой способ отформатировать дату и преобразовать ее в строку

    Date date= new Date();

    String dateStr=String.format("%td/%tm/%tY", date,date,date);

    System.out.println("Date with format of dd/mm/dd: "+dateStr);

вывод: Дата в формате дд / мм / дд: 21.10.2015

Халид Хабиб
источник
1

У Dateобъекта нет формата , это представление. Дата может быть представлена ​​значком Stringв желаемом формате .

Например, " yyyy-MM-dd", " yy-MMM-dd", " dd-MMM-yy" и т. Д.

Чтобы добиться этого, вы можете использовать SimpleDateFormat

Попробуй это,

        String inputString = "19/05/2009"; // i.e. (dd/MM/yyyy) format

        SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy"); 
        SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            Date dateFromUser = fromUser.parse(inputString); // Parse it to the exisitng date pattern and return Date type
            String dateMyFormat = myFormat.format(dateFromUser); // format it to the date pattern you prefer
            System.out.println(dateMyFormat); // outputs : 2009-05-19

        } catch (ParseException e) {
            e.printStackTrace();
        }

Это результаты: 2009-05-19

Дулит Де Коста
источник