一套新的时间API,放在java.time包下面
比之前的更加规范,并且解决了线程安全问题(最大区别)
线程安全问题
public classSimpleDateFormatTest {public static void main(String[] args) throwsException {
SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMdd");
Callable task = new Callable() {
@Overridepublic Date call() throwsException {return sdf.parse("20190105");
}
};
ExecutorService pool= Executors.newFixedThreadPool(10);
List> results = new ArrayList<>();for (int i = 0; i < 10; i++) {
results.add(pool.submit(task));
}for (Futurefuture : results) {
System.out.println(future.get());
}
}
}
旧版本解决方案
public classDateFormatThreadLocal {private static final ThreadLocal df = new ThreadLocal(){
@OverrideprotectedDateFormat initialValue() {return new SimpleDateFormat("yyyyMMdd");
}
};public static Date convert(String source) throwsParseException {returndf.get().parse(source);
}
}public classSimpleDateFormatTest {public static void main(String[] args) throwsException {
Callable task = new Callable() {
@Overridepublic Date call() throwsException {return DateFormatThreadLocal.convert("20190105");
}
};
ExecutorService pool= Executors.newFixedThreadPool(10);
List> results = new ArrayList<>();for (int i = 0; i < 10; i++) {
results.add(pool.submit(task));
}for (Futurefuture : results) {
System.out.println(future.get());
}
pool.shutdown();
}
}
Java8 解决方案
使用LocalDate日期处理类
public classSimpleDateFormatTest {public static void main(String[] args) throwsException {//Java8:DateTimeFormatter
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");//Java8:LocaleData
Callable task = new Callable() {
@Overridepublic LocalDate call() throwsException {return LocalDate.parse("20190105", dtf);
}
};
ExecutorService pool= Executors.newFixedThreadPool(10);
List> results = new ArrayList<>();for (int i = 0; i < 10; i++) {
results.add(pool.submit(task));
}for (Futurefuture : results) {
System.out.println(future.get());
}
pool.shutdown();
}
}
人读的时间
LocalDate、LocalTime、LocalDateTime的实例是不可变的的对象,分别表示ISO-8601日历系统(国际化标准组织制定的现代公民的日期和时间的表示法)的日期、时间、日期和时间,它们提供了简单的日期或时间,并不包含当前的时间和信息,和时区相关的信息。
这三者使用方法一样,LocalDateTime涵盖前两个
static voidtest1(){//使用LocalDateTime获取点前时间
LocalDateTime ldt =LocalDateTime.now();//输出当前时间
System.out.println(ldt);//指定时间
LocalDateTime ldt2 = LocalDateTime.of(2019, 01, 05, 16, 07, 33);
System.out.println(ldt2);//日期运算,改变都会产生新实例//加两年
LocalDateTime ldt3 = ldt.plusYears(2);
System.out.println(ldt3);//减两年
LocalDateTime ldt4 = ldt.minusMonths(2);
System.out.println(ldt4);//get方法,获取年月日等……
System.out.println(ldt.getYear());
System.out.println(ldt.getMonthValue());
System.out.println(ldt.getMonth().getValue());
}
机器读的时间
Instant时间戳:以UNIX元年:1970年1月1日00时00分00秒到某个时间之间的毫秒值
默认获取的时间是UTC时区的时间
static voidtest2(){//Instant时间戳:以UNIX元年:1970年1月1日00时00分00秒到某个时间之间的毫秒值
Instant ins1 = Instant.now(); //默认获取的是UTC时区
System.out.println(ins1);//偏移运算//ZoneOffset.ofHours(8) UTC-8相差8个时区
OffsetDateTime odt = ins1.atOffset(ZoneOffset.ofHours(8));
System.out.println(odt);//转成毫秒时间
System.out.println(ins1.toEpochMilli());//偏移60秒
Instant ins2 = Instant.ofEpochSecond(60);
System.out.println(ins2);
}
计算间隔
Duration:计算两个“时间”之间的间隔
static voidtest3(){//Duration:计算两个“时间”之间的间隔
Instant ins1 =Instant.now();try{
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
Instant ins2=Instant.now();
Duration dration=Duration.between(ins1, ins2);//毫秒输出
System.out.println(dration.toMillis());
System.out.println("--------------------");
LocalTime lt1=LocalTime.now();try{
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
LocalTime lt2=LocalTime.now();
Duration dration2=Duration.between(lt1, lt2);
System.out.println(dration2.toMillis());
}
Period:计算两个“日期之间的间隔”
static voidtest4(){//Period: 计算两个“日期”之间的间隔
LocalDate ld1 = LocalDate.of(2015, 1, 1);
LocalDate ld2=LocalDate.now();
Period period=Period.between(ld1, ld2);
System.out.println(period);//相差几年
System.out.println(period.getYears());
}
日期操纵
TemporalAdjuster:时间校正器。将时间调整到“下个周日”的操作,支持lambda语法
TemporalAdjusters:为TemporalAdjuster接口产生实例,该类通过静态方法提供了大量的常用TemporalAdjuster实现
static voidtest5(){//TemporalAdjuster:时间校正器
LocalDateTime ldt =LocalDateTime.now();
System.out.println(ldt);//当前月中的天指定成10日
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 ldt4=(LocalDateTime) l;//获取周几
DayOfWeek dow =ldt4.getDayOfWeek();if(dow.equals(DayOfWeek.FRIDAY)){return ldt4.plusDays(3);
}else if(dow.equals(DayOfWeek.SATURDAY)) {return ldt4.plusDays(2);
}else{return ldt.plusDays(1);
}
});
System.out.println("下个工作日");
System.out.println(ldt5);
}
格式化时间/日期
DateTimeFormatter:格式化时间/日期
static voidtest6(){//DateTimeFormatter 格式化时间/日期
DateTimeFormatter dtf =DateTimeFormatter.ISO_DATE;
LocalDateTime ldt=LocalDateTime.now();
String strDate=ldt.format(dtf);
System.out.println(strDate);
System.out.println("------------------------");
DateTimeFormatter dtf2= DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
String strDate2=dtf2.format(ldt);
System.out.println(strDate2);
System.out.println("------------------------");//将字符串解析成时间日期
LocalDateTime newDate =LocalDateTime.parse(strDate2, dtf2);
System.out.println(newDate);
}
时区的处理
ZondDate、ZondTime、ZondDateTime其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等
ZondId:该类包含了所有的时区信息
getAvailableZondIds():可以获取所有时区信息
of(id):用指定的时区信息获取ZoneId对象
static voidtest7(){//获取所有时区信息
Set set =ZoneId.getAvailableZoneIds();
set.forEach(System.out::println);
}static voidtest8(){//ZondDate、ZondTime、ZondDateTime//获取指定时区时间
LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Europe/Podgorica"));
System.out.println(ldt);//带时区的日期时间格式
LocalDateTime ldt2 = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime zdt= ldt2.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zdt);
}