1. 不够好的开始
Java 日期时间API一直是不够优秀的,再牛X的人,也不可能在每一个领域都十分擅长。爱因斯坦在理论物理上如此吊炸天,但是打一局LOL可能都不是小学生的对手。
在那些遥远的年代,Java Coder们只能用Date、Calendar、SimpleDateFormat这些类库来处理日期时间逻辑。
1.1 Date 日期时间类
Date是Java API里日期时间类库的王牌大哥大,主要用来存储、计算日期时间。常见用法:
/** * Date日期时间类Demo * @author panda * @date 2019-06-26 */ public class DateDemo { public static void main(String[] args) throws InterruptedException { //使用当前时间初始化 Date date1=new Date(); //暂停1毫秒,使两个时间值不同 Thread.sleep(1); Date date2=new Date(); //判断时间先后顺序 System.out.println("date1 after date2? "+date1.after(date2)); System.out.println("date1 before date2? "+date1.before(date2)); //判断时间,两者相等返回0,date1早于date2返回负数,date1晚于date2返回正数 System.out.println("date1 compareTO date2,result is: "+date1.compareTo(date2)); } }
OK,看着还可以,但是功能太弱,连加减日期时间的计算都做不到。
1.2 Calendar 日历类
Calendar 可以指定任意日期时间,并且可以对日期时间进行计算,但是日历这个名字起得有点土,不够正宗。
/** * Calendar日历Demo * @author panda * @date 2019-06-26 */ public class CalendarDemo { /** * 故事开始之前,先了解下JDK定义的相关常量 * Calendar.YEAR 年 * Calendar.MONTH 月 * Calendar.DATE 日 * Calendar.HOUR 小时(12小时制) * Calendar.HOUR_OF_DAY 小时(24小时制) * Calendar.MINUTE 分 * Calendar.SECOND 秒 * Calendar.DAY_OF_WEEK 星期几 */ public static void main(String[] args) { //获取当前日期对应Calendar实例 Calendar calendar1 = Calendar.getInstance(); //转换为Date System.out.println(calendar1.getTime()); //展示详细日历信息 System.out.println("" + " 年:"+calendar1.get(Calendar.YEAR) + " 月:"+calendar1.get(Calendar.MONTH) + " 日:"+calendar1.get(Calendar.DATE) + " 时:"+calendar1.get(Calendar.HOUR_OF_DAY) + " 分:"+calendar1.get(Calendar.MINUTE) + " 秒:"+calendar1.get(Calendar.SECOND) + " 星期:"+calendar1.get(Calendar.DAY_OF_WEEK)); //按年月日时分秒设置日历 Calendar calendar2=Calendar.getInstance(); calendar2.set(Calendar.YEAR, 2019); calendar2.set(Calendar.MONTH, 9);//注意月份是从0算的,0表示1月,以此类推 calendar2.set(Calendar.DATE, 1); calendar2.set(Calendar.HOUR_OF_DAY, 0); calendar2.set(Calendar.MINUTE, 0); calendar2.set(Calendar.SECOND, 0); System.out.println(calendar2.getTime()); //日期计算 calendar2.add(Calendar.YEAR, 1); calendar2.add(Calendar.DATE, -1); System.out.println(calendar2.getTime()); } }
1.3 SimpleDateFormat 日期时间格式化
OK,其实最常用的还是字符串和日期时间之间的转换,Java API里又提供了SimpleDateFormat。
/** * SimpleDateFormat格式化日期时间Demo * @author panda * @date 2019-09-26 */ public class SimpleDateFormatDemo { /** * 故事开始之前,预定义了转换格式字符串 * yyyy年、MM月份、dd日期、HH时、mm分、ss秒 * @throws ParseException */ public static void main(String[] args) throws ParseException { //当前日期 Date date1=new Date(); //定义格式 SimpleDateFormat sdf1=new SimpleDateFormat("yyyyMMdd"); SimpleDateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd"); //日期转换为对应格式字符串 非线程安全 System.out.println(sdf1.format(date1)); System.out.println(sdf2.format(date1)); //字符串转换为日期 String str="20190626"; Date date2=sdf1.parse(str); System.out.println(date2); } }
2. 足够好的JodaTime
JDK自带的日期时间类库是如此平庸,以致于我一直都记不住其类、方法名称,每次使用都感觉非常别扭。然而Java优秀的地方就是有的是非官方的解决方案,简洁、高效、优雅到爆炸。
/** * 第三方类库joda-time Demo * 需要通过maven或者jar文件导入依赖 * @author panda * @date 2019-06-26 */ public class JodaTimeDemo { public static void main(String[] args) { // 创建日期 DateTime dateTime1 = new DateTime(); System.out.println(dateTime1); // 指定日期时间创建 DateTime dateTime2 = new DateTime(2019, 10, 1, 10, 00, 00); System.out.println(dateTime2); // 格式转换 直接对象调用 System.out.println(dateTime2.toString("yyyy-MM-dd HH:mm:ss")); // 使用DateTimeFormatter进行转换(线程安全) DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); System.out.println(dtf.print(dateTime2)); // 将字符串转化为日期 String str = "2019-10-01 10:00:00"; System.out.println(dtf.parseDateTime(str)); // 直接操作对象进行日期计算 System.out.println(dateTime2.plusDays(1)); System.out.println(dateTime2.minusHours(2)); // 计算日期相差天数、月数 int days = Days.daysBetween(dateTime1, dateTime2).getDays(); int months = Months.monthsBetween(dateTime1, dateTime2).getMonths(); System.out.println(days); System.out.println(months); } }
毫无疑问,这个已经是我们自己想能到的最简单日期时间API了,而且已经帮我们实现了,还不快点用起来。
3. JDK1.8 日期时间API
像日期时间这么根基性的类库,Java也要与时俱进,于是JDK1.8带来了官方的LocalDate/LocalTime/LocalDateTime,老实说我感觉非常像是模仿的JodaTime,所以实际上JodaTime和JDK1.8日期时间API选用一个就OK了。
/** * Java8中日期时间类库Demo * * @author panda * @date 2019-06-26 */ public class Java8DateTimeDemo { public static void main(String[] args) { System.out.println("# LocalDate 日期演示"); dateDemo(); System.out.println("# LocalTime 时间演示"); timeDemo(); System.out.println("# LocalDateTime 日期时间演示"); datetimeDemo(); System.out.println("# LocalDateTime 日期时间与字符串转换演示"); formatDemo(); } // 日期演示 public static void dateDemo() { // 获取当前日期 LocalDate localDate = LocalDate.now(); System.out.println("localDate:" + localDate); // 创建指定日期 注意月份是从1开始 LocalDate myDate = LocalDate.of(2019, 6, 26); System.out.println("myDate:" + myDate); // 获取日期详情 System.out.println(myDate.getYear() + "-" + myDate.getMonthValue() + "-" + myDate.getDayOfMonth()); // 日期比较 System.out.println("是否相等:" + localDate.equals(myDate)); System.out.println("是否晚于:" + localDate.isAfter(myDate)); System.out.println("比较:" + localDate.compareTo(myDate)); // 日期加减计算 LocalDate newDate = localDate.plus(1, ChronoUnit.DAYS); System.out.println("newDate:" + newDate); } // 时间演示 public static void timeDemo() { // 获取当前时间 LocalTime localTime = LocalTime.now(); System.out.println("localTime:" + localTime); // 创建指定时间 LocalTime myTime = LocalTime.of(10, 10, 10); System.out.println("myTime:" + myTime); // 获取时间详情 System.out.println(myTime.getHour() + ":" + myTime.getMinute() + ":" + myTime.getSecond()); // 时间比较 System.out.println("是否相等:" + localTime.equals(myTime)); System.out.println("是否晚于:" + localTime.isAfter(myTime)); System.out.println("比较:" + localTime.compareTo(myTime)); // 时间加减计算 LocalTime newTime = localTime.plus(1, ChronoUnit.HOURS); System.out.println("newTime:" + newTime); } // 日期时间演示 public static void datetimeDemo() { // 获取当前日期时间 LocalDateTime now = LocalDateTime.now(); System.out.println("now:" + now); // 创建指定日期时间 LocalDateTime my = LocalDateTime.of(2019, 7, 6, 10, 10, 10); System.out.println("my:" + my); // 获取日期时间详情 System.out.println(my.getYear() + "-" + my.getMonthValue() + "-" + my.getDayOfMonth()); System.out.println(my.getHour() + ":" + my.getMinute() + ":" + my.getSecond()); // 日期时间比较 System.out.println("是否相等:" + now.equals(my)); System.out.println("是否晚于:" + now.isAfter(my)); System.out.println("比较:" + now.compareTo(my)); // 日期时间加减计算 LocalDateTime newDateTime = now.plus(1, ChronoUnit.YEARS); System.out.println("newDateTime:" + newDateTime); } // 格式化压实 public static void formatDemo() { //格式化样式类 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 日期时间转字符串 LocalDateTime now = LocalDateTime.now(); String nowStr = now.format(formatter); System.out.println("nowStr:" + nowStr); // 字符串转日期时间 String datetimeStr = "2019-07-06 10:10:10"; LocalDateTime datetime = LocalDateTime.parse(datetimeStr, formatter); System.out.println("datetime:"+datetime); } }