В Java 8 были введены три класса обработки времени: LocalDate, LocalTime и LocalDateTime, чтобы компенсировать недостатки предыдущих классов даты и времени и упростить операции с датой и временем.
Java8 Классы даты и времени включают LocalDate, LocalTime, Instant, Duration и Period, все из которых включены в пакет java.time.
До Java 8 с датой и временем работали классы Date, Calendar.
- Классы java.util.Date и java.util.Calendar не просты в использовании, не поддерживают часовые пояса и не являются потокобезопасными;
- Класс DateFormat для форматирования дат помещен в пакет java.text, это абстрактный класс, поэтому нам нужно создать экземпляр объекта SimpleDateFormat для обработки форматирования даты, а DateFormat также не является потокобезопасным, что означает, что если вы находитесь в Вызов того же объекта DateFormat в многопоточной программе приведет к неожиданным результатам.
- Метод расчета даты громоздок и подвержен ошибкам, потому что месяц начинается с 0, а месяц, полученный из календаря, должен быть добавлен на единицу для представления текущего месяца.
В настоящее время серия учебных пособий Flutter публикуется бесплатно на видео с арбузом и обновляется ежедневно Добро пожаловать, чтобы обратить внимание, чтобы получать напоминания
【x1】Нажмите, чтобы просмотреть советы
[x2] Различные серии туториалов
1 Java8 для получения данных о текущем времени
Методы now() для LocalDate и LocalDateTime используют системный часовой пояс по умолчанию.
@SpringBootTest
class DemoDateTests {
//日志
private static final Logger LOG = LoggerFactory.getLogger(DemoDateTests.class);
@Test
void test() {
//只获取当前时区的日期
LocalDate localDate = LocalDate.now();
LOG.info("localDate: " + localDate);
//localDate: 2020-09-23
//只获取当前时间
LocalTime localTime = LocalTime.now();
LOG.info("localTime: " + localTime);
//localTime: 23:41:43.991
//获取不前的日期与时间
LocalDateTime localDateTime2 = LocalDateTime.now();
LOG.info("localDateTime2: " + localDateTime2);
//localDateTime2: 2020-09-23T23:41:43.991
}
}
время, полученное здесь2020-09-23T23:41:43.991нести один посерединеTОтносится ко времени UTC.
Время UTC относится к времени в нулевом часовом поясе, а его полное название Coordinated Universal Time, то есть всемирное координированное время.
Другим распространенным сокращением является GMT, среднее время по Гринвичу.Гринвич расположен в нулевом часовом поясе.Поэтому мы обычно говорим, что время UTC и время по Гринвичу одинаковы численно.
В 1884 году Международная конференция по долготе разделила земную поверхность на 24 равных части, называемых часовыми поясами. То есть при нулевом меридиане в качестве точки отсчета диапазон 7,5 градусов восточной и западной долготы считается нулевым часовым поясом, Тогда каждые 15 градусов — это часовой пояс, каждый часовой пояс отличается на один час, а пекинский часовой пояс — это восточный восьмой округ. Например: пекинское время 2020-09-23 12:00:00, тогда время UTC будет 2020-09-23 04:00:00;
Конечно, полученный формат времени может быть не таким, как мы хотим, его можно отформатировать с помощью DateTimeFormatter следующим образом:
@Test
void test1() {
//使用静态方法生成此对象
LocalDateTime localDateTime = LocalDateTime.now();
LOG.info("localDateTime: " + localDateTime);
///localDateTime: 2020-09-23T23:47:41.752
//格式化时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss");
//格式化后的时间
String formatDate = localDateTime.format(formatter);
LOG.info("格式化之后的时间: " + formatDate);
//格式化之后的时间: 2020-09-23 23:47:41
}
1.1 LocalDate
Класс LocalDate представляет конкретную дату, но не содержит сведений о конкретном времени или часовом поясе. Экземпляр может быть создан с помощью статического метода() LocalDate. LocalDate также содержит несколько методов для получения года, месяца, дня, дня недели и т. д.
@Test
void test3() {
//当然你也可以使用当前的时间
//LocalDate localDate = LocalDate.now();
// 初始化一个日期:2020-09-24
LocalDate localDate = LocalDate.of(2020, 9, 24);
int year = localDate.getYear(); // 年份:2020
Month month = localDate.getMonth(); // 月份:SEPTEMBER
int dayOfMonth = localDate.getDayOfMonth(); // 月份中的第几天:24
DayOfWeek dayOfWeek = localDate.getDayOfWeek(); // 一周的第几天:THURSDAY
int length = localDate.lengthOfMonth(); // 月份的天数:30
boolean leapYear = localDate.isLeapYear(); // 是否为闰年:true
}
Модульный тест точки останова работает следующим образом
1.2 LocalTime
LocalTime похож на LocalDate, разница в том, что LocalDate не содержит определенного времени, а LocalTime содержит определенное время.
@Test
void test4() {
//当前的时间
LocalTime localTime = LocalTime.now();
int hour = localTime.getHour(); // 时:07
int minute = localTime.getMinute(); // 分:22
int second = localTime.getSecond(); // 秒:20
}
Модульный тест точки останова работает следующим образом
1.3 LocalDateTime
Класс LocalDateTime представляет собой комбинацию LocalDate и LocalTime, которую можно создать непосредственно методом of(), или вы можете вызвать метод atTime() LocalDate или метод atDate() LocalTime, чтобы объединить LocalDate или LocalTime в LocalDateTime.
@Test
void test5() {
///通过 of 方法创建 LocalDateTime
LocalDateTime localDateTime = LocalDateTime.of(
2020,//年
Month.JANUARY,//月
4, //日
//时 分 秒
17, 23, 52);
}
Можно понять, что преобразование LocalDate и LocalTime в LocalDateTime — это процесс их слияния, как показано ниже:
@Test
void test6() {
//通过of方法来创建 LocalDate
//参数为年 月 日
LocalDate localDate = LocalDate.of(2020, Month.JANUARY, 4);
//通过of方法来创建 LocalTime
//参数为 时分秒
LocalTime localTime = LocalTime.of(07, 23, 52);
// LocalDate 转 LocalDateTime
LocalDateTime localDateTime = localDate.atTime(localTime);
// LocalTime 转 LocalDateTime
LocalDateTime localDateTime1 = localTime.atDate(localDate);
}
Модульный тест точки останова работает следующим образом
Конечно, LocalDateTime также можно преобразовать в LocalDate или LocalTime в обратном порядке, как показано ниже:
LocalDate date = localDateTime.toLocalDate();
LocalTime time = localDateTime.toLocalTime();
2 Магические операции между LocalDateTime и миллисекундами
Отметка времени относится к общему количеству секунд с 00:00:00 01 января 1970 года по Гринвичу (08:00:00 1 января 1970 года по пекинскому времени) до настоящего времени.
ZoneId относится к региону ZoneOffset относится к данным смещения
@Test
void test2() {
//使用静态方法生成此对象
LocalDateTime localDateTime = LocalDateTime.now();
LOG.info("localDateTime: " + localDateTime);
///localDateTime: 2020-09-23T23:49:11.832
//转化为时间戳(秒)
long epochSecond = localDateTime.toEpochSecond(ZoneOffset.of("+8"));
//转化为毫秒
long epochMilli = localDateTime.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli();
LOG.info("时间戳为:(秒) " + epochSecond + "; (毫秒): " + epochMilli);
///时间戳为:(秒) 1600876151; (毫秒): 1600876151832
//时间戳(毫秒)转化成LocalDateTime
Instant instant = Instant.ofEpochMilli(epochMilli);
LocalDateTime localDateTime3 = LocalDateTime.ofInstant(instant, ZoneOffset.systemDefault());
//时间戳(秒)转化成LocalDateTime
Instant instant2 = Instant.ofEpochSecond(epochSecond);
LocalDateTime localDateTime4 = LocalDateTime.ofInstant(instant2, ZoneOffset.systemDefault());
}
3 Замечательная работа LocalDateTime и Date
Класс Instant представляет определенное время и имеет точность до наносекунд, что похоже на System.currentTimeMillis(), который мы часто используем, но Instant может быть точным до наносекунд (наносекунд), а метод System.currentTimeMillis() только с точностью до миллисекунд (Milli-Second).
Если для представления времени используются наносекунды, недостаточно использовать тип Long, и он должен занимать немного больше места для хранения.Фактически он состоит из двух полей Long.
Следует отметить, что Instant представляет собой время и не включает понятие часового пояса.
// Date 转化成 LocalDateTime
public static LocalDateTime dateToLocalDate(Date date) {
//Date转纳秒
Instant instant = date.toInstant();
//获取系统默认的时区
ZoneId zoneId = ZoneId.systemDefault();
//转化
return instant.atZone(zoneId).toLocalDateTime();
}
// LocalDateTime 转化成 Date
public static Date localDateTimeToDate(LocalDateTime localDateTime) {
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = localDateTime.atZone(zoneId);
return Date.from(zdt.toInstant());
}
// Date 毫秒数据 转化成 LocalDateTime
public static LocalDateTime dateToLocalDateMil(Long datemilli) {
//将毫秒数据转化为纳秒
Instant instant = Instant.ofEpochMilli(datemilli);
ZoneId zoneId = ZoneId.systemDefault();
return instant.atZone(zoneId).toLocalDateTime();
}
Конечно, Instant также имеет много замечательных операций.
Instant использует две внутренние константы: секунды представляют количество секунд с 1970-01-01 00:00:00 до настоящего времени, а nanos представляет наносекундную часть (значение nanos не будет превышать 999 999 999).
Помимо использования метода now() для создания Instant, его также можно создать с помощью метода ofEpochSecond:
@Test
void test7() {
//参数一为秒,参数二为纳秒,
//这里的代码表示从1970-01-01 00:00:00开始后三分钟的10万纳秒的时刻
Instant instant = Instant.ofEpochSecond(180, 100000);
LOG.info("时间为:" + instant );
}
Модульный тест точки останова работает следующим образом
4 Класс продолжительности
Этот класс не упоминается в приведенной выше операции.Внутренняя реализация Duration аналогична Instant и также состоит из двух частей: секунды представляют секунды, а нано представляют наносекунды. Разница между ними заключается в том, что Instant используется для представления метки времени (или точки времени), а Duration представляет период времени, поэтому класс Duration не содержит статического метода now(). Объекты Duration можно создавать с помощью метода Duration.between().
@Test
void test8() {
///开始时间
LocalDateTime from = LocalDateTime.of(2020, Month.JANUARY, 9, 10, 7, 0); // 2017-01-05 10:07:00
//结束时间
LocalDateTime to = LocalDateTime.of(2020, Month.FEBRUARY, 10, 10, 7, 0);
// 表示从 2020-09-05 10:07:00 到 2020-09-05 10:07:00 这段时间
Duration duration = Duration.between(from, to);
long days = duration.toDays(); // 这段时间的总天数
long hours = duration.toHours(); // 这段时间的小时数
long minutes = duration.toMinutes(); // 这段时间的分钟数
long seconds = duration.getSeconds(); // 这段时间的秒数
long milliSeconds = duration.toMillis(); // 这段时间的毫秒数
long nanoSeconds = duration.toNanos(); // 这段时间的纳秒数
LOG.info("时间为:" + duration );
}
Модульный тест точки останова работает следующим образом
5 уроков периода
Period аналогичен концепции Duration, разница в том, что Period измеряет период времени в году, месяце и дне, например, 1 год, 3 месяца и 6 дней (листинг 5-1).
Объекты Period могут быть созданы с помощью конструктора и метода between().Стоит отметить, что поскольку Period измеряет период времени по годам, месяцам и дням, метод between() может принимать только параметры типа LocalDate.
//代码清单 5-1
@Test
void test9() {
//1年3个月6天
Period period = Period.of(1, 3, 6);
// 2017-01-05 到 2017-02-05 这段时间
Period period2 = Period.between(
LocalDate.of(2020, 1, 5),
LocalDate.of(2020, 2, 5));
LOG.info("时间为:" + period );
}
Модульный тест точки останова работает следующим образом
6 Волшебная операция времени до и после указанной даты
//代码清单 6-1
@Test
void test10() {
//使用当前的时间
LocalDate localDate = LocalDate.now();
LocalDate date4 = localDate.plusYears(1); // 增加一年 2021-09-24
LocalDate date5 = localDate.minusMonths(2); // 减少两个月 2021-07-24
LocalDate date6 = localDate.plus(5, ChronoUnit.DAYS); // 增加5天 2021-09-29
LOG.info("时间为:" + date6 );
}
Модульный тест точки останова работает следующим образом
7 Отформатируйте дату
Новый API Date предоставляет класс DateTimeFormatter (также используемый выше) для обработки операций форматирования даты.Он включен в пакет java.time.format.Класс даты Java 8 имеет метод format() для форматирования даты как строки, этот метод получает и обрабатывает параметр типа DateTimeFormatter
//代码清单 7-1
@Test
void test11() {
//使用当前的时间
LocalDateTime dateTime = LocalDateTime.now();
String strDate1 = dateTime.format(DateTimeFormatter.BASIC_ISO_DATE); // 20200924
String strDate2 = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE); // 2020-09-24
String strDate3 = dateTime.format(DateTimeFormatter.ISO_LOCAL_TIME); // 08:23:31.463
String strDate4 = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 2020-09-24
LOG.info("时间为:" + dateTime );
}
Модульный тест точки останова работает следующим образомРазберите существующую строку даты на LocalDateTime, LocalDate, LocalTime, как показано в следующем листинге кода 7-2.
Основная идея синтаксического анализа заключается в том, чтобы сначала определить карту формата DateTimeFormatter, а затем вызвать соответствующий метод синтаксического анализа.
//代码清单 7-2
@Test
void test12() {
String strDate = "2020-09-24";
String strDate2 = "2020-09-24 08:23:31";
LocalDate date = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalTime time = LocalTime.parse(strDate, DateTimeFormatter.ofPattern(" HH:mm:ss"));
//定义 formatter
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//解析操作
LocalDateTime dateTime = LocalDateTime.parse(strDate2, dateTimeFormatter);
LOG.info("时间为:" + dateTime );
}
Модульный тест точки останова работает следующим образом
Конечно же есть и публичный аккаунт, заинтересованные партнеры могут обратить внимание