До JDK8 для работы с датой и временем мы в основном использовали 3 класса:Date
,SimpleDateFormat
иCalendar
.
Эти три класса имеют более или менее проблемы в использовании, такие какSimpleDateFormat
не является потокобезопасным,
НапримерDate
иCalendar
Полученный месяц — от 0 до 11, а не от 1 до 12. Это также упоминается в «Руководстве по разработке Java для Alibaba», потому что легко ошибиться:
Однако JDK8 представил новый класс обработки даты и времени для решения этих проблем, таких какInstant
,LocalDate
,LocalTime
,LocalDateTime
,DateTimeFormatter
, также рекомендуется в «Руководстве по разработке Java для Alibaba».Instant
,
LocalDateTime
,DateTimeFormatter
:
Но я обнаружил, что эти классы на самом деле не используются во многих проектах, они все еще используются раньше.Date
,SimpleDateFormat
иCalendar
Таким образом, этот блог объяснит дату и время в новом классе JDK8, в основном следующий несколько:
- Instant
- LocalDate
- LocalTime
- LocalDateTime
- DateTimeFormatter
1. Instant
1.1 Получить текущее время
теперь, когдаInstant
может заменитьDate
class, то он точно может получить текущее время:
Instant instant = Instant.now();
System.out.println(instant);
Выходной результат:
2020-06-10T08:22:13.759Z
Если вы будете внимательны, вы обнаружите, что это время на 8 часов меньше пекинского времени.Если вы хотите вывести пекинское время, вы можете добавить часовой пояс по умолчанию:
System.out.println(instant.atZone(ZoneId.systemDefault()));
Выходной результат:
2020-06-10T16:22:13.759+08:00[Asia/Shanghai]
1.2 Получить метку времени
Instant instant = Instant.now();
// 当前时间戳:单位为秒
System.out.println(instant.getEpochSecond());
// 当前时间戳:单位为毫秒
System.out.println(instant.toEpochMilli());
Выходной результат:
1591777752
1591777752613
Конечно, можно иSystem.currentTimeMillis()
Получить текущее количество миллисекунд.
1.3 Преобразование длинных в мгновенные
1) Преобразование на основе метки времени в секундах:
Instant instant = Instant.now();
System.out.println(instant);
long epochSecond = instant.getEpochSecond();
System.out.println(Instant.ofEpochSecond(epochSecond));
System.out.println(Instant.ofEpochSecond(epochSecond, instant.getNano()));
Выходной результат:
2020-06-10T08:40:54.046Z
2020-06-10T08:40:54Z
2020-06-10T08:40:54.046Z
2) Преобразование на основе метки времени в миллисекундах:
Instant instant = Instant.now();
System.out.println(instant);
long epochMilli = instant.toEpochMilli();
System.out.println(Instant.ofEpochMilli(epochMilli));
Выходной результат:
2020-06-10T08:43:25.607Z
2020-06-10T08:43:25.607Z
1.4 Преобразование строки в Instant
String text = "2020-06-10T08:46:55.967Z";
Instant parseInstant = Instant.parse(text);
System.out.println("秒时间戳:" + parseInstant.getEpochSecond());
System.out.println("豪秒时间戳:" + parseInstant.toEpochMilli());
System.out.println("纳秒:" + parseInstant.getNano());
Выходной результат:
Вторая метка времени: 1591778815
Отметка времени в миллисекундах: 1591778815967
Наносекунды: 967000000
Например, если формат строки неверен, измените его на2020-06-10T08:46:55.967
, это броситjava.time.format.DateTimeParseException
исключение, как показано на следующем рисунке:
2. LocalDate
2.1 Получить текущую дату
использоватьLocalDate
Получить текущую дату так же просто, как это:
LocalDate today = LocalDate.now();
System.out.println("today: " + today);
Выходной результат:
today: 2020-06-10
Без какого-либо форматирования вывод очень удобный, если вы используетеDate
, выводить в таком формате, надо сотрудничатьSimpleDateFormat
уточнитьyyyy-MM-dd
При форматировании случайно будет баг, типа очень популярный баг в конце прошлого года, я еще тогда сделал скриншот:
Эти два друга подписались на меня 31.12.2019, но когда я проверил 2 января 2020 года, это отображалось как 31.12.2020, почему? Неправильный формат при форматировании даты, он должен бытьyyyy/MM/dd
, но пишется какYYYY/MM/dd
, это просто произошло на той неделе, и он отображался как следующий год, то есть 2020. В то время несколько блоггеров написали статьи для анализа причин, поэтому я не буду здесь слишком много объяснять.
Фокус: Сказав это, я дам вам свой недавно зарегистрированный публичный аккаунт "Shencheng Stranger" для всех. Пожалуйста, обратите внимание. Вас ждут новые оригинальные статьи, ха-ха.
2.2 Получить год месяц день
LocalDate today = LocalDate.now();
int year = today.getYear();
int month = today.getMonthValue();
int day = today.getDayOfMonth();
System.out.println("year: " + year);
System.out.println("month: " + month);
System.out.println("day: " + day);
Выходной результат:
year: 2020
month: 6
day: 10
Получить месяц, наконец, возвращает от 1 до 12, в отличие отjava.util.Calendar
Получить месяц возвращает от 0 до 11, и вы должны добавить 1 после его получения.
2.3 Назначенная дата
LocalDate specifiedDate = LocalDate.of(2020, 6, 1);
System.out.println("specifiedDate: " + specifiedDate);
Выходной результат:
specifiedDate: 2020-06-01
Если месяц определен, рекомендуется использовать другой перегруженный метод, использующий перечисление для указания месяца:
LocalDate specifiedDate = LocalDate.of(2020, Month.JUNE, 1);
2.4 Сравните даты на равенство
LocalDate localDate1 = LocalDate.now();
LocalDate localDate2 = LocalDate.of(2020, 6, 10);
if (localDate1.equals(localDate2)) {
System.out.println("localDate1 equals localDate2");
}
Выходной результат:
localDate1 equals localDate2
2.5 Датой приобретения является день недели/месяца/года
LocalDate today = LocalDate.now();
System.out.println("Today:" + today);
System.out.println("Today is:" + today.getDayOfWeek());
System.out.println("今天是本周的第" + today.getDayOfWeek().getValue() + "天");
System.out.println("今天是本月的第" + today.getDayOfMonth() + "天");
System.out.println("今天是本年的第" + today.getDayOfYear() + "天");
Выходной результат:
Today:2020-06-11
Today is:THURSDAY
Сегодня 4-й день недели
Сегодня 11 число месяца
Сегодня 163-й день года
2.6 Определить, является ли год високосным
LocalDate today = LocalDate.now();
System.out.println(today.getYear() + " is leap year:" + today.isLeapYear());
Выходной результат:
2020 is leap year:true
3. LocalTime
3.1 Получить часы, минуты и секунды
При использованииjava.util.Date
, код выглядит следующим образом:
Date date = new Date();
int hour = date.getHours();
int minute = date.getMinutes();
int second = date.getSeconds();
System.out.println("hour: " + hour);
System.out.println("minute: " + minute);
System.out.println("second: " + second);
Выходной результат:
Примечание: Эти методы устарели, поэтому настоятельно не рекомендуется использовать их в проектах:
При использованииjava.util.Calendar
, код выглядит следующим образом:
Calendar calendar = Calendar.getInstance();
// 12小时制
int hourOf12 = calendar.get(Calendar.HOUR);
// 24小时制
int hourOf24 = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int milliSecond = calendar.get(Calendar.MILLISECOND);
System.out.println("hourOf12: " + hourOf12);
System.out.println("hourOf24: " + hourOf24);
System.out.println("minute: " + minute);
System.out.println("second: " + second);
System.out.println("milliSecond: " + milliSecond);
Выходной результат:
**Примечания.** При получении часа есть 2 варианта: 1 возвращает час в 12-часовом формате, а 1 возвращает час в 24-часовом формате, потому что сейчас 20:00, поэтомуcalendar.get(Calendar.HOUR)
возвращает 8, аcalendar.get(Calendar.HOUR_OF_DAY)
возвращает 20.
При использованииjava.time.LocalTime
, код выглядит следующим образом:
LocalTime localTime = LocalTime.now();
System.out.println("localTime:" + localTime);
int hour = localTime.getHour();
int minute = localTime.getMinute();
int second = localTime.getSecond();
System.out.println("hour: " + hour);
System.out.println("minute: " + minute);
System.out.println("second: " + second);
Выходной результат:
Видно, что в LocalTime есть только время, а не дата.
4. LocalDateTime
4.1 Получить текущее время
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime:" + localDateTime);
Выходной результат:
localDateTime: 2020-06-11T11:03:21.376
4.2 Получить год, месяц, день, час, минуту и секунду
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime: " + localDateTime);
System.out.println("year: " + localDateTime.getYear());
System.out.println("month: " + localDateTime.getMonthValue());
System.out.println("day: " + localDateTime.getDayOfMonth());
System.out.println("hour: " + localDateTime.getHour());
System.out.println("minute: " + localDateTime.getMinute());
System.out.println("second: " + localDateTime.getSecond());
Выходной результат:
4.3 Добавить дни/часы
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime: " + localDateTime);
LocalDateTime tomorrow = localDateTime.plusDays(1);
System.out.println("tomorrow: " + tomorrow);
LocalDateTime nextHour = localDateTime.plusHours(1);
System.out.println("nextHour: " + nextHour);
Выходной результат:
localDateTime: 2020-06-11T11:13:44.979
tomorrow: 2020-06-12T11:13:44.979
nextHour: 2020-06-11T12:13:44.979
LocalDateTime
Существуют также методы добавления лет, недель, минут и секунд, которые здесь не перечислены:
4.4 Сокращенные дни/часы
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime: " + localDateTime);
LocalDateTime yesterday = localDateTime.minusDays(1);
System.out.println("yesterday: " + yesterday);
LocalDateTime lastHour = localDateTime.minusHours(1);
System.out.println("lastHour: " + lastHour);
Выходной результат:
localDateTime: 2020-06-11T11:20:38.896
yesterday: 2020-06-10T11:20:38.896
lastHour: 2020-06-11T10:20:38.896
сродни,LocalDateTime
Он также предоставляет методы сокращения лет, недель, минут и секунд, которые здесь не перечислены:
4.5 Время получения - день недели/года
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime: " + localDateTime);
System.out.println("DayOfWeek: " + localDateTime.getDayOfWeek().getValue());
System.out.println("DayOfYear: " + localDateTime.getDayOfYear());
Выходной результат:
localDateTime: 2020-06-11T11:32:31.731
DayOfWeek: 4
DayOfYear: 163
5. DateTimeFormatter
Представлено в JDK8java.time.format.DateTimeFormatter
Чтобы решить проблему форматирования даты, также рекомендуется использовать в «Руководстве по разработке Java для Alibaba»DateTimeFormatter
заменятьSimpleDateFormat
.
5.1 Форматирование LocalDate
LocalDate localDate = LocalDate.now();
System.out.println("ISO_DATE: " + localDate.format(DateTimeFormatter.ISO_DATE));
System.out.println("BASIC_ISO_DATE: " + localDate.format(DateTimeFormatter.BASIC_ISO_DATE));
System.out.println("ISO_WEEK_DATE: " + localDate.format(DateTimeFormatter.ISO_WEEK_DATE));
System.out.println("ISO_ORDINAL_DATE: " + localDate.format(DateTimeFormatter.ISO_ORDINAL_DATE));
Выходной результат:
Если предоставленный формат не соответствует вашим потребностям, вы также можете настроить формат, как и раньше:
LocalDate localDate = LocalDate.now();
System.out.println("yyyy/MM/dd: " + localDate.format(DateTimeFormatter.ofPattern("yyyy/MM/dd")));
Выходной результат:
yyyy/MM/dd: 2020/06/11
5.2 Форматирование местного времени
LocalTime localTime = LocalTime.now();
System.out.println(localTime);
System.out.println("ISO_TIME: " + localTime.format(DateTimeFormatter.ISO_TIME));
System.out.println("HH:mm:ss: " + localTime.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
Выходной результат:
14:28:35.230
ISO_TIME: 14:28:35.23
HH:mm:ss: 14:28:35
5.3 Форматирование LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
System.out.println("ISO_DATE_TIME: " + localDateTime.format(DateTimeFormatter.ISO_DATE_TIME));
System.out.println("ISO_DATE: " + localDateTime.format(DateTimeFormatter.ISO_DATE));
Выходной результат:
2020-06-11T14:33:18.303
ISO_DATE_TIME: 2020-06-11T14:33:18.303
ISO_DATE: 2020-06-11
6. Преобразование типов
6.1 Мгновенно к дате
JDK8,Date
недавно добавленныйfrom()
метод, будетInstant
преобразовать вDate
, код выглядит так:
Instant instant = Instant.now();
System.out.println(instant);
Date dateFromInstant = Date.from(instant);
System.out.println(dateFromInstant);
Выходной результат:
2020-06-11T06:39:34.979Z
Thu Jun 11 14:39:34 CST 2020
6.2 Дата для мгновенного
JDK8,Date
недавно добавленныйtoInstant
метод, будетDate
преобразовать вInstant
, код выглядит так:
Date date = new Date();
Instant dateToInstant = date.toInstant();
System.out.println(date);
System.out.println(dateToInstant);
Выходной результат:
Thu Jun 11 14:46:12 CST 2020
2020-06-11T06:46:12.112Z
6.3 Дата в LocalDateTime
Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime localDateTimeOfInstant = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
System.out.println(date);
System.out.println(localDateTimeOfInstant);
Выходной результат:
Thu Jun 11 14:51:07 CST 2020
2020-06-11T14:51:07.904
6.4 Дата в LocalDate
Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime localDateTimeOfInstant = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
LocalDate localDate = localDateTimeOfInstant.toLocalDate();
System.out.println(date);
System.out.println(localDate);
Выходной результат:
Thu Jun 11 14:59:38 CST 2020
2020-06-11
Как можно видеть,Date
сначала преобразуется вInstant
, а затем преобразовать вLocalDateTime
, то черезLocalDateTime
ПолучатьLocalDate
.
6.5 Дата в местное время
Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime localDateTimeOfInstant = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
LocalTime toLocalTime = localDateTimeOfInstant.toLocalTime();
System.out.println(date);
System.out.println(toLocalTime);
Выходной результат:
Thu Jun 11 15:06:14 CST 2020
15:06:14.531
Как можно видеть,Date
сначала преобразуется вInstant
, а затем преобразовать вLocalDateTime
, то черезLocalDateTime
ПолучатьLocalTime
.
6.6 LocalDateTime до даты
LocalDateTime localDateTime = LocalDateTime.now();
Instant toInstant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date dateFromInstant = Date.from(toInstant);
System.out.println(localDateTime);
System.out.println(dateFromInstant);
Выходной результат:
2020-06-11T15:12:11.600
Thu Jun 11 15:12:11 CST 2020
6.7 LocalDate to Date
LocalDate today = LocalDate.now();
LocalDateTime localDateTime = localDate.atStartOfDay();
Instant toInstant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date dateFromLocalDate = Date.from(toInstant);
System.out.println(dateFromLocalDate);
Выходной результат:
Thu Jun 11 00:00:00 CST 2020
6.8 Преобразование местного времени в дату
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
Instant instantFromLocalTime = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date dateFromLocalTime = Date.from(instantFromLocalTime);
System.out.println(dateFromLocalTime);
Выходной результат:
Thu Jun 11 15:24:18 CST 2020
7. Резюме
JDK8 представил новые классы даты и времени, такие какInstant
,LocaleDate
,LocalTime
,LocalDateTime
,DateTimeFormatter
, дизайн стал более разумным, чем раньше, а также поточно-ориентированным.
Это также рекомендуется в «Спецификации разработки Java для Alibaba».Instant
заменятьDate
,LocalDateTime
заменятьCalendar
,DateTimeFormatter
заменятьSimpleDateFormat
.
Поэтому, если позволяют условия, рекомендуется использовать его в проекте, а если не используется, рассмотреть возможность апгрейда.
Примечание. Если вы считаете, что в этом блоге есть какие-либо ошибки или лучшие предложения, оставьте сообщение, я слежу и вовремя исправлю содержание блога!
Статья будет постоянно обновляться, пожалуйста, обратите внимание на общедоступный аккаунт WeChat «Shencheng Stranger», чтобы прочитать ее впервые!