Преобразование строки Java в дату
Какой наилучший способ преобразовать a String
в формате '2 января 2010' в a Date
в Java?
В конечном счете, я хочу разделить месяц, день и год на целые числа, чтобы я мог использовать
Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();
для преобразования даты во время.
Переведено автоматически
Ответ 1
Это сложный путь, и эти java.util.Date
методы настройки устарели со времен Java 1.1 (1997). Более того, весь java.util.Date
класс де-факто устарел (не рекомендуется) с момента появления java.time
API в Java 8 (2014).
Просто отформатируйте дату с помощью DateTimeFormatter
шаблона, соответствующего входной строке (руководство доступно здесь).
В вашем конкретном случае "2 января 2010" в качестве входной строки:
- "Январь" - это полный текстовый месяц, поэтому используйте для него
MMMM
шаблон - "2" - это сокращенный день месяца, поэтому используйте для него шаблон
d
. - "2010" - это 4-значный год, поэтому используйте для него
yyyy
шаблон.
String string = "January 2, 2010";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(string, formatter);
System.out.println(date); // 2010-01-02
Примечание: если ваш шаблон форматирования также содержит временную часть, тогда используйте LocalDateTime#parse(text, formatter)
вместо LocalDate#parse(text, formatter)
. И, если ваш шаблон формата также содержит часовой пояс, используйте ZonedDateTime#parse(text, formatter)
вместо этого.
Вот соответствующая выдержка из javadoc, в которой перечислены все доступные шаблоны форматирования:
Символ | Значение | Презентация | Примеры |
---|---|---|---|
G | эпоха | текст | AD; Anno Domini; A |
u | год | год | 2004; 04 |
y | год выпуска | год | 2004; 04 |
D | день года | количество | 189 |
M /L | месяц года | число / текст | 7; 07; Июля; July; J |
d | день месяца | количество | 10 |
Q /q | квартал за год | число / текст | 3; 03; 3 квартал; 3-й квартал |
Y | в зависимости от недели-год | год | 1996; 96 |
w | по неделям в зависимости от года | количество | 27 |
W | неделя месяца | количество | 4 |
E | день недели | текст | Вт; Tuesday; T |
e /c | локализованный день недели | число / текст | 2; 02; Вт; Вторник; T |
F | неделя месяца | количество | 3 |
a | с утра до вечера текущего дня | текст | PM |
h | часы-время-утра-вечера (1-12) | количество | 12 |
K | время от утра до вечера (0-11) | количество | 0 |
k | часы-время-утра-вечера (1-24) | количество | 0 |
H | время суток (0-23) | количество | 0 |
m | количество минут в час | количество | 30 |
s | секунда в минуту | количество | 55 |
S | доля секунды | дробь | 978 |
A | количество за миллион дней | количество | 1234 |
n | доли секунды | количество | 987654321 |
N | новинка дня | количество | 1234000000 |
V | идентификатор часового пояса | идентификатор зоны | Америка/Los_Angeles; Z; -08:30 |
z | название часового пояса | название зоны | Стандартное тихоокеанское время; PST |
O | локализованная зона-смещение | смещение-O | GMT+8; GMT +08:00; UTC-08:00; |
X | зона-смещение 'Z' вместо нуля | смещение-X | Z; -08; -0830; -08:30; -083015; -08:30:15; |
x | смещение зоны | смещение-x | +0000; -08; -0830; -08:30; -083015; -08:30:15; |
Z | смещение зоны | смещение-Z | +0000; -0800; -08:00; |
Обратите внимание, что в нем есть несколько предопределенных форматеров для более популярных шаблонов. Поэтому вместо, например, DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
вы могли бы использовать DateTimeFormatter.RFC_1123_DATE_TIME
. Это возможно, потому что они, в отличие от SimpleDateFormat
, потокобезопасны. Таким образом, при необходимости вы также можете определить свои собственные.
Для определенного формата входной строки вам не нужно использовать явный DateTimeFormatter
: стандартная дата ISO 8601, например 2016-09-26T17:44:57Z, может быть проанализирована напрямую с помощью LocalDateTime#parse(text)
поскольку она уже использует ISO_LOCAL_DATE_TIME
форматировщик. Аналогично, LocalDate#parse(text)
анализирует дату ISO без компонента времени (см. ISO_LOCAL_DATE
) и ZonedDateTime#parse(text)
анализирует дату ISO со смещением и добавлением часового пояса (см. ISO_ZONED_DATE_TIME
).
До Java 8
Если вы еще не используете Java 8 или вынуждены использовать java.util.Date
, то отформатируйте дату с помощью SimpleDateFormat
шаблона формата, соответствующего входной строке.
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
Обратите внимание на важность явного Locale
аргумента. Если вы опустите это, то будет использоваться язык по умолчанию, который не обязательно является английским, как используется в названии месяца входной строки. Если языковой стандарт не совпадает с входной строкой, то вы ошибочно получите java.text.ParseException
, даже если шаблон формата кажется допустимым.
Вот соответствующая выдержка из javadoc, в которой перечислены все доступные шаблоны форматирования:
Письмо | Компонент даты или времени | Презентация | Примеры |
---|---|---|---|
G | Обозначение эпохи | Текст | ОБЪЯВЛЕНИЕ |
y | Год | Год | 1996; 96 |
Y | Неделя, год | Год | 2009; 09 |
M /L | Месяц в году | Месяц | Июль; Jul; 07 |
w | Неделя в году | Число | 27 |
W | Неделя в месяце | Число | 2 |
D | День в году | Число | 189 |
d | Число в месяце | Число | 10 |
F | День недели в месяце | Число | 2 |
E | День в неделе | Текст | Вторник; Вт |
u | Номер дня недели | Число | 1 |
a | Маркер утра / вечера | Текст | PM |
H | Час в сутках (0-23) | Число | 0 |
k | Час в сутках (1-24) | Число | 24 |
K | Время в часах утра / вечера (0-11) | Число | 0 |
h | Время в часах утра / вечера (1-12) | Число | 12 |
m | Минута в час | Число | 30 |
s | Секунда в минуте | Число | 55 |
S | Миллисекунда | Число | 978 |
z | Часовой пояс | Общий часовой пояс | Стандартное тихоокеанское время; PST; GMT-08:00 |
Z | Часовой пояс | Часовой пояс RFC 822 | -0800 |
X | Часовой пояс | Часовой пояс ISO 8601 | -08; -0800; -08:00 |
Обратите внимание, что шаблоны чувствительны к регистру и что текстовые шаблоны из четырех символов или более представляют полную форму; в противном случае используется краткая или сокращенная форма, если таковая имеется. Так, например, MMMMM
или больше нет необходимости.
Вот несколько примеров допустимых SimpleDateFormat
шаблонов для анализа заданной строки на дату:
Входная строка | Шаблон |
---|---|
2001.07.04 Объявление в 12:08:56 PDT | yyyy.MM.dd G 'at' HH:mm:ss z |
Ср., 4 июля '01 | EEE, MMM d, ''yy |
12:08 | h:mm a |
12 часов вечера по Тихоокеанскому летнему времени | hh 'o''clock' a, zzzz |
09:08 PDT | K:mm a, z |
02001.Июль.04 AD 12:08 | yyyyy.MMMM.dd GGG hh:mm aaa |
Ср., 4 июля 2001 г. 12:08:56 -0700 | EEE, d MMM yyyy HH:mm:ss Z |
010704120856-0700 | yyMMddHHmmssZ |
2001-07-04T12:08:56.235-0700 | yyyy-MM-dd'T'HH:mm:ss.SSSZ |
2001-07-04T12:08:56.235-07:00 | yyyy-MM-dd'T'HH:mm:ss.SSSXXX |
2001-W27-3 | YYYY-'W'ww-u |
Важное замечание заключается в том, что SimpleDateFormat
это не потокобезопасно. Другими словами, вы никогда не должны объявлять и назначать ее как статическую переменную или переменный экземпляра, а затем повторно использовать ее из разных методов / потоков. Вы всегда должны создавать ее совершенно новой в локальной области действия метода.
Ответ 2
Ах да, опять обсуждение даты Java. Для работы с датами мы используем Date, Calendar, 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));
Ответ 3
String str_date = "11-June-07";
DateFormat formatter = new SimpleDateFormat("dd-MMM-yy");
Date date = formatter.parse(str_date);
Ответ 4
С Java 8 мы получаем новый API даты / времени (JSR 310).
Для анализа даты в Java 8 можно использовать следующий способ, не полагаясь на Joda-Time:
String str = "January 2nd, 2010";
// if we 2nd even we have changed in pattern also it is not working please workout with 2nd
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM Q, 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;