1. 概述

1.1 简介

Java 8 引入了一套全新的时间日期API,操作起来更简便。简单介绍下,LocalDateLocalTimeLocalDateTime的使用;

java.util.Date月份从0开始,java.time.LocalDate月份从1开始并且提供了枚举。

java.util.DateSimpleDateFormatter都不是线程安全的,而LocalDateLocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改,它们分别使用 ISO-8601 日历系统的日期和时间,它们提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。

注 : ISO-8601 日历系统是国际标准化组织制定的现代公民的日期和时间的表示法

1.3 环境

2. LocalDate、LocalTime、LocalDateTime

LocalDateLocalTimeLocalDateTime 三者的使用方式基本一致,所以我们这里就以 LocalDateTime 为例进行索命

2.1 实例

@Test
public void t1() {
// 获取当前时间
LocalDateTime ldt1 = LocalDateTime.now();
System.out.println(ldt1); // 获取指定的时间
LocalDateTime ldt2 = LocalDateTime.of(2018, 12, 10, 10, 10, 10);
System.out.println(ldt2); // 加两年
LocalDateTime ldt3 = ldt1.plusYears(2);
System.out.println(ldt3); // 减两个月
LocalDateTime ldt4 = ldt1.minusYears(2);
System.out.println(ldt4); // 获取年月日时分秒
System.out.println(ldt1.getYear());
System.out.println(ldt1.getMonthValue());
System.out.println(ldt1.getDayOfMonth());
System.out.println(ldt1.getHour());
System.out.println(ldt1.getMinute());
System.out.println(ldt1.getSecond());
}

2.2 Instant : 时间戳

使用 Unix 元年 1970年1月1日 00:00:00 所经历的毫秒值

@Test
public void t2() {
Instant ins = Instant.now(); //默认使用 UTC 时区
System.out.println(ins); // 时间偏移量
OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));
System.out.println(odt); // 获取毫秒值
System.out.println(ins.getNano()); // 对于元年开始进行运算
Instant ins2 = Instant.ofEpochSecond(60);
System.out.println(ins2);
}

2.3 Duration : 用于计算两个“时间”间隔

@Test
public void t3() throws InterruptedException {
// 时间戳
Instant ins1 = Instant.now(); Thread.sleep(1000); Instant ins2 = Instant.now();
Duration duration = Duration.between(ins1, ins2);
System.out.println("所耗费时间为:" + duration.toMillis()); System.out.println("--------------------------------"); // LocalTime
LocalTime lt1 = LocalTime.now(); Thread.sleep(1000); LocalTime lt2 = LocalTime.now(); System.out.println("所耗费时间为:" + Duration.between(lt1, lt2).toMillis());
}

2.4 Period : 用于计算两个“日期”间隔

@Test
public void t5() {
LocalDate ld1 = LocalDate.of(2017, 1, 1);
LocalDate ld2 = LocalDate.now();
Period period = Period.between(ld1, ld2);
System.out.println("相差" + period.getYears() + "年" + period.getMonths() + "月" + period.getDays() + "天");
}

2.5 日期的操作

TemporalAdjuster 时间校正器,有时我们可能需要获取例如:将日期调整到下个周日等操作。

TemporalAdjusters 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现。

@Test
public void t6() {
LocalDateTime ldt = LocalDateTime.now(); // 指定这个月的一个固定日期
LocalDateTime ldt2 = ldt.withDayOfMonth(10);
System.out.println(ldt2); // 获取下个周日
LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println("获取下个周日 : " + ldt3); // 自定义:获取下个工作日
LocalDateTime ldt5 = ldt.with((l) -> {
LocalDateTime ldt6 = (LocalDateTime) l;
DayOfWeek dayOfWeek = ldt6.getDayOfWeek(); if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
return ldt6.plusDays(3);
} else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
return ldt6.plusDays(2);
} else {
return ldt6.plusDays(1);
}
});
System.out.println("获取下个工作日 : " + ldt5);
}

3. DateTimeFormatter

3.1 简介

在 JDK 1.8 中可以使用 DateTimeFormatter 来代替 SimpleDateFormat 进行日期的格式化,而且 DateTimeFormatter 是线程安全的

3.2 实例

@Test
public void t8() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = LocalDateTime.now(); // 将日期格式化为字符串,两种方式否可以
String dtfDate = dtf.format(ldt);
String ldtDate = ldt.format(dtf);
System.out.println("dtfDate : " + dtfDate);
System.out.println("ldtDate : " + ldtDate); // 将字符串格式化为 LocalDateTime
LocalDateTime ldt2 = LocalDateTime.parse(dtfDate, dtf);
System.out.println("时间为 : " + ldt2);
}

3.3 线程安全

在多线程使用 SimpleDateFormat 进行格式化日期的时候会有线程安全问题。

@Test
public void t1() throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
return sdf.parse("2018-12-10");
}
}; ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<Date>> results = new ArrayList<>();
for (int i = 0; i < 10; i++) {
results.add(executor.submit(task));
} for (Future<Date> future : results) {
System.out.println(future.get());
}
executor.shutdown();
}

可以使用 ThreadLocal 的锁解决 SimpleDateFormat 的线程安全问题

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; public class DateFormatThreadLocal {
private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
}; public static final Date convert(String source) throws ParseException {
return df.get().parse(source);
}
}

测试方法

@Test
public void t2() throws Exception {
Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
return DateFormatThreadLocal.convert("2018-12-10");
}
}; ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<Date>> results = new ArrayList<>();
for (int i = 0; i < 10; i++) {
results.add(executor.submit(task));
} for (Future<Date> future : results) {
System.out.println(future.get());
}
executor.shutdown();
}

使用 DateTimeFormatter 进行格式化,DateTimeFormatter 是线程安全的

@Test
public void t3() throws Exception {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); Callable<LocalDate> task = new Callable<LocalDate>() {
@Override
public LocalDate call() throws Exception {
return LocalDate.parse("2018-12-10",dtf);
}
}; ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<LocalDate>> results = new ArrayList<>();
for (int i = 0; i < 10; i++) {
results.add(executor.submit(task));
} for (Future<LocalDate> future : results) {
System.out.println(future.get());
}
executor.shutdown();
}

4. 时区设置

@Test
public void t2() {
LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println(ldt); // 带时区的时间
ZonedDateTime zdt = ldt.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zdt);
}

本文首发于凌风博客:Java 8 新的时间日期 API
作者:凌风

Java 8 新的时间日期 API的更多相关文章

  1. Java 8新的时间日期库的20个使用示例

    原文链接 作者:Javin Paul 译者:之诸暇 除了lambda表达式,stream以及几个小的改进之外,Java 8还引入了一套全新的时间日期API,在本篇教程中我们将通过几个简单的任务示例来学 ...

  2. Java 8新的时间日期库,这二十个案例看完你还学不会算我的!!!

    Java对日期,日历及时间的处理一直以来都饱受诟病,尤其是它决定将java.util.Date定义为可修改的以及将SimpleDateFormat实现成非线程安全的.看来Java已经意识到需要为时间及 ...

  3. JAVA8学习——新的时间日期API&Java8总结

    JAVA8-时间日期API java8之前用过的时间日期类. Date Calendar SimpleDateFormat 有很多致命的问题. 1.没有时区概念 2.计算麻烦,实现困难 3.类是可变的 ...

  4. java8新特性——时间日期API

    传统的时间 API 存在线程安全的问题,在多线程开发中必须要上锁,所以 java8 现在为我们提供了一套全新的时间日期 API ,今天进来学习一下java8 的时间日期 API. 一.使用 Local ...

  5. 【java】JDK1.8时间日期库 新特性 所有java中时间Date的使用

    除了lambda表达式,stream以及几个小的改进之外,Java 8还引入了一套全新的时间日期API,在本篇教程中我们将通过几个简单的任务示例来学习如何使用java 8的这套API.Java对日期, ...

  6. Java8新特性时间日期库DateTime API及示例

    Java8新特性的功能已经更新了不少篇幅了,今天重点讲解时间日期库中DateTime相关处理.同样的,如果你现在依旧在项目中使用传统Date.Calendar和SimpleDateFormat等API ...

  7. java8新的时间日期库及使用示例

    转自:https://www.cnblogs.com/comeboo/p/5378922.html 来自:Java译站 链接:http://it.deepinmind.com/java/2015/03 ...

  8. Java 8 的时间日期 API

    上一篇文章『Java 的时间日期 API』中,我们学习了由 Date.Calendar,DateFormat 等组成的「传统时间日期 API」,但是传统的处理接口设计并不是很友好,不易使用.终于,Ja ...

  9. Java8新特性(三)——Optional类、接口方法与新时间日期API

    一.Optional容器类 这是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. 查看结构图可以看到有如下常用方法: of(T)—— ...

随机推荐

  1. Machine Learning--决策树(一)

    决策树(decision tree):是机器学习常见的算法之一.是基于树形结构进行决策的. 讲决策树就要提到“信息熵”.“信息增益”.“增益率”和“基尼指数”的概念. 我们先来介绍一下这几个概念:(讲 ...

  2. 【深度学习一】tensorflow安装

    一. 安装Anaconda https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ 二.安装tensorflow conda install --cha ...

  3. vector容器中添加和删除元素

    添加元素: 方法一: insert() 插入元素到Vector中 iterator insert( iterator loc, const TYPE &val ); //在指定位置loc前插入 ...

  4. Laravel 视图中的url

    <a href="{{ url('url') }}">url</a> <a href="{{ action('StudentControll ...

  5. laravel 查询构造器2

    //查询构造器 public function query() { //获取所有的数据 $student = DB::table('student')->get(); var_dump($stu ...

  6. treetable 用法小例

    插件地址:http://pan.baidu.com/s/1kVf0Kcfcript src="/plugins/jQuery/jQuery-2.1.4.min.js">< ...

  7. (2)git本地生成SSH关联github

    1.安装git 2.打开 Git Bash 输入ssh ,查看是否安装了ssh 这个界面是安装了的意思 3.生成ssh 输入ssh-keygen -t rsa 指令, 再连续按三次回车 会生成两个文件 ...

  8. HDU 4341 Gold miner(分组背包)

    题目链接 Gold miner 目标是要在规定时间内获得的价值总和要尽可能大. 我们先用并查集把斜率相同的物品分在同一个组. 这些组里的物品按照y坐标的大小升序排序. 如果组内的一个物品被选取了,那该 ...

  9. codevs——2152 滑雪

    2152 滑雪  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description trs喜欢滑雪.他来到了一个滑雪场,这个滑雪场 ...

  10. codevs——1294 全排列

    1294 全排列  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 给出一个n, 请输出n的所有全 ...