本文源码: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 20211611904285848
计算规定
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-parentGitEE·地址https://gitee.com/cicadasmile/java-base-parent
浏览标签
【Java根底】【设计模式】【构造与算法】【Linux零碎】【数据库】
【分布式架构】【微服务】【大数据组件】【SpringBoot进阶】【Spring&Boot根底】
【数据分析】【技术导图】【 职场】