[Глубокие размышления] Как использовать тип даты в JDK8?

Java

До 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, в основном следующий несколько:

  1. Instant
  2. LocalDate
  3. LocalTime
  4. LocalDateTime
  5. DateTimeFormatter

1. Instant

1.1 Получить текущее время

теперь, когдаInstantможет заменитьDateclass, то он точно может получить текущее время:

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», чтобы прочитать ее впервые!