Преобразование строки Java в дату

каков наилучший способ преобразования a String в формате '2 января 2010 года на Date в Java?

В конечном счете, я хочу разбить месяц, день и год на целые числа, чтобы я мог использовать

Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();

для преобразования даты во время.

14 ответов


это трудный путь, и те java.util.Date методы сеттера устарели с Java 1.1 (1997). просто формат даты, используя SimpleDateFormat Использование шаблона формата, соответствующего входной строке.

в вашем конкретном случае "январь 2, 2010" в качестве входной строки:

  1. "январь" - это полнотекстовый месяц, поэтому используйте MMMM шаблон для нее
  2. " 2 " - короткий день месяца, поэтому используйте d шаблон для он.
  3. "2010" -это 4-значный год, поэтому используйте yyyy шаблон для него.

String string = "January 2, 2010";
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
System.out.println(date); // Sat Jan 02 00:00:00 GMT 2010

обратите внимание на важность явного


Ах да, обсуждение даты Java, снова. Для работы с манипуляцией датой мы используем дата, календарь, GregorianCalendar и SimpleDateFormat. Например, используя дату января в качестве входных данных:

Calendar mydate = new GregorianCalendar();
String mystring = "January 2, 2010";
Date thedate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(mystring);
mydate.setTime(thedate);
//breakdown
System.out.println("mydate -> "+mydate);
System.out.println("year   -> "+mydate.get(Calendar.YEAR));
System.out.println("month  -> "+mydate.get(Calendar.MONTH));
System.out.println("dom    -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow    -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour   -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli  -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm   -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod    -> "+mydate.get(Calendar.HOUR_OF_DAY));

тогда вы можете манипулировать этим с чем-то вроде:

Calendar now = Calendar.getInstance();
mydate.set(Calendar.YEAR,2009);
mydate.set(Calendar.MONTH,Calendar.FEBRUARY);
mydate.set(Calendar.DAY_OF_MONTH,25);
mydate.set(Calendar.HOUR_OF_DAY,now.get(Calendar.HOUR_OF_DAY));
mydate.set(Calendar.MINUTE,now.get(Calendar.MINUTE));
mydate.set(Calendar.SECOND,now.get(Calendar.SECOND));
// or with one statement
//mydate.set(2009, Calendar.FEBRUARY, 25, now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
System.out.println("mydate -> "+mydate);
System.out.println("year   -> "+mydate.get(Calendar.YEAR));
System.out.println("month  -> "+mydate.get(Calendar.MONTH));
System.out.println("dom    -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow    -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour   -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli  -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm   -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod    -> "+mydate.get(Calendar.HOUR_OF_DAY));

String str_date = "11-June-07";
DateFormat formatter;
Date date;
formatter = new SimpleDateFormat("dd-MMM-yy");
date = formatter.parse(str_date);

С Java 8 мы получаем новый API даты / времени (JSR 310).

для анализа даты в Java 8 можно использовать следующий способ, не полагаясь на Joda Времени:

String str = "January 2, 2010";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(str, formatter);

// access date fields
int year = date.getYear(); // 2010
int day = date.getDayOfMonth(); // 2
Month month = date.getMonth(); // JANUARY
int monthAsInt = month.getValue(); // 1

LocalDate стандартный класс Java 8 для представления даты (без времени). Если вы хотите проанализировать значения, содержащие информацию о дате и времени, вы должны использовать LocalDateTime. Для значений с часовыми поясами используйте ZonedDateTime. Оба обеспечивают parse() аналогично LocalDate:

LocalDateTime dateWithTime = LocalDateTime.parse(strWithDateAndTime, dateTimeFormatter);
ZonedDateTime zoned = ZonedDateTime.parse(strWithTimeZone, zoneFormatter);

список символов форматирования из DateTimeFormatter Javadoc:

All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. 
The following pattern letters are defined:

Symbol  Meaning                     Presentation      Examples
------  -------                     ------------      -------
 G       era                         text              AD; Anno Domini; A
 u       year                        year              2004; 04
 y       year-of-era                 year              2004; 04
 D       day-of-year                 number            189
 M/L     month-of-year               number/text       7; 07; Jul; July; J
 d       day-of-month                number            10

 Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
 Y       week-based-year             year              1996; 96
 w       week-of-week-based-year     number            27
 W       week-of-month               number            4
 E       day-of-week                 text              Tue; Tuesday; T
 e/c     localized day-of-week       number/text       2; 02; Tue; Tuesday; T
 F       week-of-month               number            3

 a       am-pm-of-day                text              PM
 h       clock-hour-of-am-pm (1-12)  number            12
 K       hour-of-am-pm (0-11)        number            0
 k       clock-hour-of-am-pm (1-24)  number            0

 H       hour-of-day (0-23)          number            0
 m       minute-of-hour              number            30
 s       second-of-minute            number            55
 S       fraction-of-second          fraction          978
 A       milli-of-day                number            1234
 n       nano-of-second              number            987654321
 N       nano-of-day                 number            1234000000

 V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
 z       time-zone name              zone-name         Pacific Standard Time; PST
 O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
 X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
 x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
 Z       zone-offset                 offset-Z          +0000; -0800; -08:00;

хотя некоторые из ответов технически правильны, они не рекомендуется.

  • java.утиль.Классы Date & Calendar, как известно, хлопотно. Из-за недостатков в дизайне и реализации избегайте их. К счастью, у нас есть выбор из двух других отличных библиотек даты и времени:
    • Joda Времени
      эта популярная бесплатная библиотека с открытым исходным кодом может использоваться в нескольких версиях Java. Много примеров его использование можно найти в StackOverflow. Чтение некоторых из них поможет вам быстро войти в курс дела.
    • java.время.* пакет
      этот новый набор классов вдохновлен Joda-Time и определен JSR 310. Эти классы встроены в Java 8. В настоящее время осуществляется проект для backport этих классов в Java 7, но этот backporting не поддерживается Oracle.
  • Как правильно отметил Кристофер Джонсон в своем комментарии к вопрос, другие ответы игнорируют жизненно важные вопросы:
    • времени
      дата имеет как часть даты, так и часть времени суток)
    • Часовой Пояс
      начало дня зависит от часового пояса. Если не удается указать часовой пояс, применяется часовой пояс JVM по умолчанию. Это означает, что поведение кода может измениться при запуске на других компьютерах или с измененной настройкой часового пояса. Наверное, не то, что ты хотеть.
    • Locale
      язык локали определяет, как интерпретировать слова (имя месяца и дня), встречающиеся во время синтаксического анализа. (The ответ BalusC обрабатывает это правильно.) Кроме того, Локаль влияет на выходные данные некоторых форматеров при создании строкового представления даты-времени.

Joda Времени

несколько заметок о Joda-Time следуют.

время Зона

на Joda Времени, a DateTime объект действительно знает свой собственный назначенный часовой пояс. Это контрастирует с java.утиль.Класс даты, который кажется иметь часовой пояс, но не.

обратите внимание в примере кода ниже, как мы передаем объект часового пояса в форматер, который анализирует строку. Этот часовой пояс используется для интерпретации этой даты-времени как произошедшего в этом часовом поясе. Поэтому вам нужно подумать и определить время зона, представленная строковым вводом.

поскольку у вас нет временной части во входной строке, Joda-Time назначает первый момент дня указанного часового пояса в качестве времени суток. Обычно это означает 00:00:00 но не всегда, из-за летнее время (DST) или другие аномалии. Кстати, вы можете сделать то же самое с любым экземпляром DateTime, вызвав withTimeAtStartOfDay.

Форматирования Шаблон

символы, используемые в шаблоне форматирования похожи в Joda-Time на те, что на java.утиль.Дата / календарь, но не совсем то же самое. Внимательно прочитайте документ.

неизменяемости

мы обычно используем неизменяемые классы в Joda-Time. Вместо того чтобы изменять существующий объект даты и времени, мы вызываем методы, которые создают новый экземпляр на основе другого объекта с копированием большинства аспектов, за исключением тех, где требуются изменения. Примером является вызов withZone в последней строке ниже. неизменяемости помогает сделать Joda-Time очень потокобезопасен, а также может сделать некоторую работу более ясной.

преобразование

вам понадобится java.утиль.Объекты Date для использования с другими классами / фреймворком, которые не знают об объектах Joda-Time. К счастью, двигаться вперед и назад очень легко.

переход от java.утиль.Объект Date (здесь имя date) в Joda-Time DateTime...

org.joda.time.DateTime dateTime = new DateTime( date, timeZone );

переход в другом направлении от Joda-Time к java.утиль.Дата объект...

java.util.Date date = dateTime.toDate();

Пример Кода

String input = "January 2, 2010";

java.util.Locale locale = java.util.Locale.US;
DateTimeZone timeZone = DateTimeZone.forID( "Pacific/Honolulu" ); // Arbitrarily chosen for example.
DateTimeFormatter formatter = DateTimeFormat.forPattern( "MMMM d, yyyy" ).withZone( timeZone ).withLocale( locale );
DateTime dateTime = formatter.parseDateTime( input );

System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTime in UTC/GMT: " + dateTime.withZone( DateTimeZone.UTC ) );

при запуске...

dateTime: 2010-01-02T00:00:00.000-10:00
dateTime in UTC/GMT: 2010-01-02T10:00:00.000Z

при работе с классом SimpleDateFormat важно помнить, что Date не является потокобезопасным, и вы не можете совместно использовать один объект Date с несколькими потоками.

также большая разница между "М" и " М " где небольшой случай использован для минут и случай столицы использован на месяц. То же самое с "d" и "D". Это может вызвать тонкие ошибки, которые часто упускаются из виду. См.Javadoc или руководство по преобразованию строки в дату в Java для получения более подробной информации.


    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date date;
    try {
        date = dateFormat.parse("2013-12-4");
        System.out.println(date.toString()); // Wed Dec 04 00:00:00 CST 2013

        String output = dateFormat.format(date);
        System.out.println(output); // 2013-12-04
    } 
    catch (ParseException e) {
        e.printStackTrace();
    }

он отлично работает для меня.


кроме того, SimpleDateFormat недоступен с некоторыми клиентскими технологиями, такими как GWT.

Это хорошая идея, чтобы пойти на календарь.getInstance (), и ваше требование-сравнить две даты; перейти на длинную дату.


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

моя тестовая программа:

package be.test.package.time;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

public class TimeWork {

    public static void main(String[] args) {    

        TimeZone timezone = TimeZone.getTimeZone("UTC");

        List<Long> longs = new ArrayList<>();
        List<String> strings = new ArrayList<>();

        //Formatting a date needs a timezone - otherwise the date get formatted to your system time zone.
        //Use 24h format HH. In 12h format hh can be in range 0-11, which makes 12 overflow to 0.
        DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS");
        formatter.setTimeZone(timezone);

        Date now = new Date();

        //Test dates
        strings.add(formatter.format(now));
        strings.add("01-01-1970 00:00:00.000");
        strings.add("01-01-1970 00:00:01.000");
        strings.add("01-01-1970 00:01:00.000");
        strings.add("01-01-1970 01:00:00.000");
        strings.add("01-01-1970 10:00:00.000");
        strings.add("01-01-1970 12:00:00.000");
        strings.add("01-01-1970 24:00:00.000");
        strings.add("02-01-1970 00:00:00.000");
        strings.add("01-01-1971 00:00:00.000");
        strings.add("01-01-2014 00:00:00.000");
        strings.add("31-12-1969 23:59:59.000");
        strings.add("31-12-1969 23:59:00.000");
        strings.add("31-12-1969 23:00:00.000");

        //Test data
        longs.add(now.getTime());
        longs.add(-1L);
        longs.add(0L); //Long date presentation at - midnight 1/1/1970 UTC - The timezone is important!
        longs.add(1L);
        longs.add(1000L);
        longs.add(60000L);
        longs.add(3600000L);
        longs.add(36000000L);
        longs.add(43200000L);
        longs.add(86400000L);
        longs.add(31536000000L);
        longs.add(1388534400000L);
        longs.add(7260000L);
        longs.add(1417706084037L);
        longs.add(-7260000L);

        System.out.println("===== String to long =====");

        //Show the long value of the date
        for (String string: strings) {
            try {
                Date date = formatter.parse(string);
                System.out.println("Formated date : " + string + " = Long = " + date.getTime());
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        System.out.println("===== Long to String =====");

        //Show the date behind the long
        for (Long lo : longs) {
            Date date = new Date(lo);
            String string = formatter.format(date);
            System.out.println("Formated date : " + string + " = Long = " + lo);        
        }
    }
}

результаты теста:

===== String to long =====
Formated date : 05-12-2014 10:17:34.873 = Long = 1417774654873
Formated date : 01-01-1970 00:00:00.000 = Long = 0
Formated date : 01-01-1970 00:00:01.000 = Long = 1000
Formated date : 01-01-1970 00:01:00.000 = Long = 60000
Formated date : 01-01-1970 01:00:00.000 = Long = 3600000
Formated date : 01-01-1970 10:00:00.000 = Long = 36000000
Formated date : 01-01-1970 12:00:00.000 = Long = 43200000
Formated date : 01-01-1970 24:00:00.000 = Long = 86400000
Formated date : 02-01-1970 00:00:00.000 = Long = 86400000
Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000
Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000
Formated date : 31-12-1969 23:59:59.000 = Long = -1000
Formated date : 31-12-1969 23:59:00.000 = Long = -60000
Formated date : 31-12-1969 23:00:00.000 = Long = -3600000
===== Long to String =====
Formated date : 05-12-2014 10:17:34.873 = Long = 1417774654873
Formated date : 31-12-1969 23:59:59.999 = Long = -1
Formated date : 01-01-1970 00:00:00.000 = Long = 0
Formated date : 01-01-1970 00:00:00.001 = Long = 1
Formated date : 01-01-1970 00:00:01.000 = Long = 1000
Formated date : 01-01-1970 00:01:00.000 = Long = 60000
Formated date : 01-01-1970 01:00:00.000 = Long = 3600000
Formated date : 01-01-1970 10:00:00.000 = Long = 36000000
Formated date : 01-01-1970 12:00:00.000 = Long = 43200000
Formated date : 02-01-1970 00:00:00.000 = Long = 86400000
Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000
Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000
Formated date : 01-01-1970 02:01:00.000 = Long = 7260000
Formated date : 04-12-2014 15:14:44.037 = Long = 1417706084037
Formated date : 31-12-1969 21:59:00.000 = Long = -7260000

простые два форматера, которые мы использовали:

  1. какой формат даты вы хотите?
  2. какой формат дата на самом деле присутствует?

мы анализируем полный формат даты и времени:

date="2016-05-06 16:40:32";

public static String setDateParsing(String date) throws ParseException {

    // This is the format date we want
    DateFormat mSDF = new SimpleDateFormat("hh:mm a");

    // This format date is actually present
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd hh:mm");
    return mSDF.format(formatter.parse(date));
}

вы можете использовать SimpleDateformat для изменения строки на дату

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String strDate = "2000-01-01";
Date date = new Date(sdf.parse(strDate).getTime());

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

Я написал интересную утилиту. Вот статья, которая описывает эту идею: в Java 8 на Java.пакет времени: разбор любой строки на дату. Это было реализовано в Java 8, но идея может быть реализована и в более ранних версиях.


на Android

календарь.getInstance ().методов gettime() дает

Thu Jul 26 15:54:13 GMT+05:30 2018

использовать

String oldDate = "Thu Jul 26 15:54:13 GMT+05:30 2018";
DateFormat format = new SimpleDateFormat("EEE LLL dd HH:mm:ss Z yyyy");
Date updateLast = format.parse(oldDate);

попробуй такое

String date = get_pump_data.getString("bond_end_date");
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date datee = (Date)format.parse(date);