本文源码:GitHub·点这里 || GitEE·点这里
一、工夫和日期
在零碎开发中,日期与工夫作为重要的业务因素,起到非常要害的作用,例如同一个工夫节点下的数据生成,基于工夫范畴的各种数据统计和剖析,集群节点对立工夫防止超时等。
在工夫和日期中有几个要害概念:
- 日期:通常年月日的组合示意以后日期。
- 工夫:通常时分秒的组合示意以后工夫。
- 时区:世界各国家与地区经度不同,划分 24 个标准时区,相邻时区的工夫相差一个小时。
- 工夫戳:从 UTC 工夫的
1970-1-1 00:00:00
起到当初的总秒数。
日期和工夫的用法在零碎中通常是获取工夫和一些常见的计算与格局转换解决,在一些垮时区的业务中就会变的简单很多,例如在电商业务中的寰球贸易或者海淘等。
二、JDK 原生 API
1、Date 根底
根底用法
java.sql.Date 继承 java.util.Date,相干办法也大部分间接调用父类办法。
public class DateTime01 {public static void main(String[] args) {long nowTime = System.currentTimeMillis() ;
java.util.Date data01 = new java.util.Date(nowTime);
java.sql.Date date02 = new java.sql.Date(nowTime);
System.out.println(data01);
System.out.println(date02.getTime());
}
}
打印:Fri Jan 29 15:11:25 CST 2021
1611904285848
计算规定
public class DateTime02 {public static void main(String[] args) {Date nowDate = new Date();
System.out.println("年:"+nowDate.getYear());
System.out.println("月:"+nowDate.getMonth());
System.out.println("日:"+nowDate.getDay());
}
}
年份:以后工夫减去 1900;
public int getYear() {return normalize().getYear() - 1900;}
月份:0-11 示意 1 -12 月份;
public int getMonth() {return normalize().getMonth() - 1;}
天份:失常示意;
public int getDay() {return normalize().getDayOfWeek() - BaseCalendar.SUNDAY;}
格局转换
非线程平安的日期转换 API,该用法在标准的开发中是不容许应用的。
public class DateTime02 {public static void main(String[] args) throws Exception {
// 默认转换
DateFormat dateFormat01 = new SimpleDateFormat() ;
String nowDate01 = dateFormat01.format(new Date()) ;
System.out.println("nowDate01="+nowDate01);
// 指定格局转换
String format = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat dateFormat02 = new SimpleDateFormat(format);
String nowDate02 = dateFormat02.format(new Date()) ;
System.out.println("nowDate02="+nowDate02);
// 解析工夫
String parse = "yyyy-MM-dd HH:mm";
SimpleDateFormat dateFormat03 = new SimpleDateFormat(parse);
Date parseDate = dateFormat03.parse("2021-01-18 16:59:59") ;
System.out.println("parseDate="+parseDate);
}
}
作为 JDK 初始版本就应用的日期和工夫,Date 类始终在我的项目中应用,然而相干 API 的办法都曾经根本废除,通常应用一些二次封装的工夫组件。该 API 的设计堪称 Java 中的最烂。
2、Calendar 降级
Calendar 作为一个抽象类,定义日期工夫相干转换与计算的办法,这个类目测
public class DateTime04 {public static void main(String[] args) {Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR,2021);
calendar.set(Calendar.MONTH,1);
calendar.set(Calendar.DAY_OF_MONTH,12);
calendar.set(Calendar.HOUR_OF_DAY,23);
calendar.set(Calendar.MINUTE,59);
calendar.set(Calendar.SECOND,59);
calendar.set(Calendar.MILLISECOND,0);
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
Date defDate = calendar.getTime();
System.out.println(defDate+"||"+dateFormat.format(defDate));
}
}
输入:Fri Feb 12 23:59:59 CST 2021||2021-02-12 23:59:59
直观感觉,Date 中相干办法迁徙 Calendar 实现,简化 Date 的性能偏重对日期与工夫的实体封装,Calendar 简单相干计算策略,DateFormat 仍旧用来做格局解决。然而 Calendar 仍旧很少被应用,上述根底 API 就曾经是很好的阐明了。
3、JDK1.8 降级 API
Java8 之后的版本中,外围 API 类包含 LocalDate- 日期、LocalTime- 工夫、LocalDateTime- 日期加工夫。
- LocalDate:日期形容是 final 润饰的不可变类,默认格局 yyyy-MM-dd。
- LocalTime:工夫形容是 final 润饰的不可变类,默认格局 hh:mm:ss.zzz。
- LocalDateTime:日期与工夫形容 final 润饰的不可变类。
public class DateTime05 {public static void main(String[] args) {
// 日期:年 - 月 - 日
System.out.println(LocalDate.now());
// 工夫:时 - 分 - 秒 - 毫秒
System.out.println(LocalTime.now());
// 日期工夫:年 - 月 - 日 时 - 分 - 秒 - 毫秒
System.out.println(LocalDateTime.now());
// 日期节点获取
LocalDate localDate = LocalDate.now();
System.out.println("[" + localDate.getYear() +
"年];[" + localDate.getMonthValue() +
"月];[" + localDate.getDayOfMonth()+"日]");
// 计算方法
System.out.println("1 年后:" + localDate.plusYears(1));
System.out.println("2 月前:" + localDate.minusMonths(2));
System.out.println("3 周后:" + localDate.plusWeeks(3));
System.out.println("3 天前:" + localDate.minusDays(3));
// 工夫比拟
LocalTime localTime1 = LocalTime.of(12, 45, 45); ;
LocalTime localTime2 = LocalTime.of(16, 30, 30); ;
System.out.println(localTime1.isAfter(localTime2));
System.out.println(localTime2.isAfter(localTime1));
System.out.println(localTime2.equals(localTime1));
// 日期和工夫格局
LocalDateTime localDateTime = LocalDateTime.now() ;
LocalDate myLocalDate = localDateTime.toLocalDate();
LocalTime myLocalTime = localDateTime.toLocalTime();
System.out.println("日期:" + myLocalDate);
System.out.println("工夫:" + myLocalTime);
}
}
如果作为 JodaTime 组件的深度用户,对这个几个 API 应用根本无压力。
4、工夫戳
工夫戳也是业务中罕用的形式,基于 Long 类型示意工夫,在很多时候远比惯例日期与工夫的格局更好用。
public class DateTime06 {public static void main(String[] args) {
// 准确到毫秒级别
System.out.println(System.currentTimeMillis());
System.out.println(new Date().getTime());
System.out.println(Calendar.getInstance().getTime().getTime());
System.out.println(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
}
}
这里须要留神的是在理论业务中因为获取工夫戳的形式是多样的,所以倡议对立工具办法,和规定精确度,防止局部准确到秒局部准确到毫秒的问题,这样能够躲避在应用时互相转换的状况。
三、JodaTime 组件
在 Java8 之前 JodaTime 组件是大部分零碎中的常见抉择,有很多不便好用的日期与工夫的解决办法封装。
根底依赖:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
在 joda-time 提供的组件之上做一个简略的工具类封装,保障业务解决格调对立。
public class JodaTimeUtil {
// 工夫格局
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private JodaTimeUtil (){}
// 获取以后工夫
public static DateTime getCurrentTime (){return new DateTime() ;
}
// 获取指定工夫
public static DateTime getDateTime (Object obj){return new DateTime(obj) ;
}
// 把工夫以指定格局转换为字符串
public static String getNowDate (Date date, String format){return new DateTime(date).toString(format) ;
}
// 获取星期工夫
public static String getWeek (Object date){DateTime time = getDateTime (date) ;
String week = null ;
switch (time.getDayOfWeek()) {
case DateTimeConstants.SUNDAY:
week = "星期日";
break;
case DateTimeConstants.MONDAY:
week = "星期一";
break;
case DateTimeConstants.TUESDAY:
week = "星期二";
break;
case DateTimeConstants.WEDNESDAY:
week = "星期三";
break;
case DateTimeConstants.THURSDAY:
week = "星期四";
break;
case DateTimeConstants.FRIDAY:
week = "星期五";
break;
case DateTimeConstants.SATURDAY:
week = "星期六";
break;
default:
break;
}
return week ;
}
}
四、源代码地址
GitHub·地址
https://github.com/cicadasmile/java-base-parent
GitEE·地址
https://gitee.com/cicadasmile/java-base-parent
浏览标签
【Java 根底】【设计模式】【构造与算法】【Linux 零碎】【数据库】
【分布式架构】【微服务】【大数据组件】【SpringBoot 进阶】【Spring&Boot 根底】
【数据分析】【技术导图】【职场】