在Java8之前,时间日期API存在线程安全的问题,多线程情况下需要加锁,并且使用起来也比较不方便。Java8为我们提供了新的时间日期API。这篇文章,我们一起来使用下。
LocalDate
、 LocalTime
、 LocalDateTime
类的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。
注: ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法
接下来,我们就以LocalDateTime
为例,其它2个类使用方法一样,这里不再赘述。
/** * 获取当前时间 */
@Test
public void test1() {
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
}
Output:
2019-05-30T21:36:49.269
/** * 创建指定日期 */
@Test
public void test2(){
LocalDateTime dateTime = LocalDateTime.of(2019, 5, 30, 21, 41, 10);
System.out.println(dateTime);
}
Output:
2019-05-30T21:41:10
/** * 日期加减运算 */
@Test
public void test3(){
LocalDateTime now = LocalDateTime.of(2019, 5, 30, 21, 45, 10);
LocalDateTime plusTime = now.plusYears(1) // 加一年
.plusMonths(2) // 加2月
.plusDays(3) // 加三天
.plusHours(4) // 加4小时
.plusMinutes(5) // 加5分钟
.plusSeconds(6); // 加6秒
System.out.println(plusTime);
LocalDateTime minusTime = now.minusYears(1) // 减一年
.minusMonths(2) // 减2月
.minusDays(3) // 减 3天
.minusHours(4) // 减4小时
.minusMinutes(5) // 减5分钟
.minusSeconds(6); // 减6秒
System.out.println(minusTime);
}
Output:
2020-08-03T01:50:16
2018-03-27T17:40:04
/** * 修改月份天数、月份、年份为指定值返回新的LocalDate对象 */
@Test
public void test4(){
LocalDate today = LocalDate.of(2019, 5, 30);
LocalDate date = today.withYear(2020) // 将年份修改为2010年
.withMonth(10) // 修改月份为10月
.withDayOfMonth(24); // 修改月份天数为24号
System.out.println(date);
}
Output:
2020-10-24
/** * 获取日期年月日等 */
@Test
public void test5(){
LocalDate today = LocalDate.of(2019, 5, 30);
System.out.println(today.getDayOfMonth()); // 月份天数(1-31)
System.out.println(today.getDayOfYear()); // 年份天数(1-366)
System.out.println(today.getDayOfWeek()); // 星期几(返回一个DayOfWeek枚举值)
System.out.println(today.getMonth()); // 月份,返回一个Month枚举值
System.out.println(today.getMonthValue()); // 返回具体的月份值(1-12)
System.out.println(today.getYear()); // 返回年份的具体值,如2019
}
Output:
30
150
THURSDAY
MAY
5
2019
/** * until获取2个日期间的Period对象或者指定的ChronoUnit的数字 */
@Test
public void test6(){
LocalDate date = LocalDate.of(2018, 10, 24);
LocalDate today = LocalDate.of(2019, 5, 30);
Period period = date.until(today);
System.out.println(period);
long until = date.until(LocalDate.of(2018, 5, 21), ChronoUnit.MONTHS); // 2个日期间,按月相差多少
System.out.println(until);
}
Output:
P7M6D // 相差7个月6天
-5 // 小5个月
/** * 比较2个LocalDate前后 */
@Test
public void test7(){
LocalDate date1 = LocalDate.of(2018, 5, 21);
LocalDate date2 = LocalDate.of(2018, 10, 24);
System.out.println(date1.isBefore(date2)); // date1在date2之前?返回true
System.out.println(date2.isAfter(date1)); // date2在date1之后?返回true
}
/** * 判断是否闰年 */
@Test
public void test8(){
LocalDate date1 = LocalDate.of(2020, 5, 21);
LocalDate date2 = LocalDate.of(2019, 5, 30);
System.out.println(date1.isLeapYear()); // true
System.out.println(date2.isLeapYear()); // false
}
用于“时间戳”的运算。它是以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的描述进行运算
/** * Instant获取当前时间戳 */
@Test
public void test9(){
long milli = Instant.now().toEpochMilli();
System.out.println(milli);
System.out.println(System.currentTimeMillis());
}
Output:
1559226655246
1559226655246
/** * Duration计算2个时间差 */
@Test
public void test10(){
LocalDateTime now = LocalDateTime.of(2019, 5, 30, 22, 32, 10);
LocalDateTime time = LocalDateTime.of(2019, 5, 30, 10, 20, 11);
Duration duration = Duration.between(time, now);
System.out.println(duration);
}
Output:
PT12H11M59S // 相差12小时11分钟59秒
/** * 计算2个LocalDate之间差 */
@Test
public void test11(){
LocalDate today = LocalDate.of(2019, 5, 30);
LocalDate date = LocalDate.of(2018, 3, 27);
Period period = Period.between(date, today);
System.out.println(period);
}
Output:
P1Y2M3D // 相差1年2月3天
TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下个周日”等操作。
TemporalAdjusters : 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现。
/** * 下一个周五 */
@Test
public void test12(){
LocalDate nextFri = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
System.out.println(nextFri);
}
ava.time.format.DateTimeFormatter 类:该类提供了三种格式化方法:
/** * The printer and/or parser to use, not null. */
private final CompositePrinterParser printerParser;
/** * The locale to use for formatting, not null. */
private final Locale locale;
/** * The symbols to use for formatting, not null. */
private final DecimalStyle decimalStyle;
/** * The resolver style to use, not null. */
private final ResolverStyle resolverStyle;
/** * The fields to use in resolving, null for all fields. */
private final Set<TemporalField> resolverFields;
/** * The chronology to use for formatting, null for no override. */
private final Chronology chrono;
/** * The zone to use for formatting, null for no override. */
private final ZoneId zone;
/** * 自定义格式化日期 */
@Test
public void test13(){
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");
String time = now.format(dtf);
System.out.println(time);
LocalDateTime dateTime = LocalDateTime.parse("20181024 20:21:22", dtf);
System.out.println(dateTime);
}
Output:
20190530 22:49:48
2018-10-24T20:21:22
Java8 中加入了对时区的支持,带时区的时间为分别为:
ZonedDate、 ZonedTime、 ZonedDateTime
其中每个时区都对应着 ID,地区ID都为 “{区域}/{城市}”的格式
例如 : Asia/Shanghai 等
ZoneId:该类中包含了所有的时区信息
getAvailableZoneIds() : 可以获取所有时区时区信息
of(id) : 用指定的时区信息获取 ZoneId 对象
类 | To 遗留类 | From 遗留类 |
---|---|---|
java.time.Instant java.util.Date | Date.from(instant) | date.toInstant() |
java.time.Instant java.sql.Timestamp | Timestamp.from(instant) | timestamp.toInstant() |
java.time.ZonedDateTime java.util.GregorianCalendar | GregorianCalendar.from(zonedDateTim e) | cal.toZonedDateTime() |
java.time.LocalDate java.sql.Time | Date.valueOf(localDate) | date.toLocalDate() |
java.time.LocalTime java.sql.Time | Date.valueOf(localDate) | date.toLocalTime() |
java.time.LocalDateTime java.sql.Timestamp | Timestamp.valueOf(localDateTime) | timestamp.toLocalDateTime() |
java.time.ZoneId java.util.TimeZone | Timezone.getTimeZone(id) | timeZone.toZoneId() |
java.time.format.DateTimeFormatter java.text.DateFormat | formatter.toFormat() | 无 |
原文地址:https://xudc.tech/2019/05/30/java8-date-time-api/