Преобразование строки Java в дату
что является лучшим способом, чтобы преобразовать String
в формате '2 января 2010 года на Date
в Java?
В конечном счете, я хочу разбить месяц, день и год как целые числа, чтобы я мог использовать
Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();
для преобразования даты во время.
14 ответов:
это трудный путь, и те
java.util.Date
методы setter были устаревшими с Java 1.1 (1997). просто отформатируйте дату с помощьюSimpleDateFormat
используя шаблон формата, соответствующий входной строке.в вашем конкретном случае "2 января 2010 года" в качестве входной строки:
- "январь" - это полнотекстовый месяц, поэтому используйте
MMMM
шаблон для нее- "2" - это короткий день месяца, поэтому используйте
d
шаблон для оно.- "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.утиль.Дата и календарь классы, как известно, хлопотно. Из-за недостатков в дизайне и реализации, избегайте их. К счастью, у нас есть выбор из двух других отличных библиотек даты и времени:
- Joda Времени
эта популярная бесплатная библиотека с открытым исходным кодом может использоваться в нескольких версиях Java. Много примеров его использование можно найти на StackOverflow. Чтение некоторых из них поможет вам быстро войти в курс дела.- java.время.* пакет
этот новый набор классов вдохновлен Joda-Time и определяется JSR 310. Эти классы встроены в Java 8. В настоящее время ведется проект по обратному переносу этих классов в Java 7, но этот обратный перенос не поддерживается Oracle.- Как правильно отметил Кристофер Джонсон в своем комментарии вопрос, другие ответы игнорируют жизненно важные вопросы:
- времени
дата имеет как часть даты, так и часть времени суток)- Часовой Пояс
начало дня зависит от часового пояса. Если вы не можете указать часовой пояс, применяется часовой пояс по умолчанию JVM. Это означает, что поведение кода может измениться при запуске на других компьютерах или с измененной настройкой часового пояса. Наверное, не то, что вы хотеть.- Locale
язык локали определяет, как интерпретировать слова (имя месяца и дня), встречающиеся во время синтаксического анализа. (Тег ответ от BalusC обрабатывает это правильно.) Кроме того, Локаль влияет на вывод некоторые средства форматирования при создании строкового представления даты-времени.Joda Времени
несколько заметок о Joda-Time следуют.
время Зона
на Joda Времени, a DateTime объект действительно знает свой собственный назначенный часовой пояс. Это контрастирует с java.утиль.Класс даты, который кажется иметь часовой пояс, но не.
обратите внимание в приведенном ниже примере кода, как мы передаем объект часового пояса в модуль форматирования, который анализирует строку. Этот часовой пояс используется для интерпретации этой даты-времени как произошедшего в этом часовом поясе. Так что нужно подумать и определиться со временем зона, представленная этим строковым входом.
поскольку у вас нет временной части во входной строке, Joda-Time назначает первый момент дня указанного часового пояса в качестве времени суток. Обычно это означает
00:00:00
но не всегда, из-за переход на летнее время (DST) или другие аномалии. Кстати, вы можете сделать то же самое с любым экземпляром DateTime, вызвавwithTimeAtStartOfDay
.Форматирования Шаблон
символы, используемые в шаблоне модуля форматирования похожи в Joda-Time на те, что в java.утиль.Дата / календарь, но не совсем то же самое. Внимательно прочитайте документ.
неизменяемости
мы обычно используем неизменяемые классы в Joda-Time. Вместо того чтобы изменять существующий объект даты-времени, мы вызываем методы, которые создают новый свежий экземпляр на основе другого объекта с большинством скопированных аспектов, за исключением тех, где изменения были желательны. Примером является вызов
withZone
в последней строке ниже. неизменяемости помогает сделать Joda-время очень потокобезопасное, а также может сделать некоторые работы более понятными.преобразование
вам понадобится java.утиль.Объекты Date для использования с другими классами / фреймворками, которые не знают об объектах Joda-Time. К счастью, это очень легко двигаться вперед и назад.
переход от java.утиль.Объект даты (здесь называется
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 с несколькими потоками.
также существует большая разница между "m" и "M", где малый случай используется в течение нескольких минут, а капитальный случай используется в течение месяца. То же самое с "d" и "D". Это может вызвать тонкие ошибки, которые часто упускают из виду. Смотрите документация или руководство по преобразованию строки в дату в 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
простые два форматера, которые мы использовали:
- какой формат даты вы хотите?
- какой формат даты на самом деле нет?
мы анализируем полный формат даты и времени:
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, но идея может быть реализована и в более ранних версиях.