介绍

日期时间包是Hutool的核心包之一,提供针对JDK中Date和Calendar对象的封装,封装对象如下:

日期时间工具

  • DateUtil 针对日期时间操作提供一系列静态方法
  • DateTime 提供类似于Joda-Time中日期时间对象的封装,继承自Date类,并提供更加丰富的对象方法。
  • FastDateFormat 提供线程安全的针对Date对象的格式化和日期字符串解析支持。此对象在实际使用中并不需要感知,相关操作已经封装在DateUtilDateTime的相关方法中。
  • DateBetween 计算两个时间间隔的类,除了通过构造新对象使用外,相关操作也已封装在DateUtilDateTime的相关方法中。
  • TimeInterval 一个简单的计时器类,常用于计算某段代码的执行时间,提供包括毫秒、秒、分、时、天、周等各种单位的花费时长计算,对象的静态构造已封装在DateUtil中。
  • DatePattern 提供常用的日期格式化模式,包括String类型和FastDateFormat两种类型。

    日期枚举

    考虑到Calendar类中表示时间的字段(field)都是使用int表示,在使用中非常不便,因此针对这些int字段,封装了与之对应的Enum枚举类,这些枚举类在DateUtilDateTime相关方法中做为参数使用,可以更大限度的缩小参数限定范围。
    这些定义的枚举值可以通过getValue()方法获得其与Calendar类对应的int值,通过of(int)方法从Calendar中int值转为枚举对象。
    Calendar对应的这些枚举包括:

  • Month 表示月份,与Calendar中的int值一一对应。

  • Week 表示周,与Calendar中的int值一一对应

另外,Hutool还定义了季度枚举。Season.SPRING为第一季度,表示1~3月。季度的概念并不等同于季节,因为季节与月份并不对应,季度常用于统计概念。

时间枚举

时间枚举DateUnit主要表示某个时间单位对应的毫秒数,常用于计算时间差。
例如:DateUnit.MINUTE表示分,也表示一分钟的毫米数,可以通过调用其getMillis()方法获得其毫秒数。

日期时间工具-DateUtil

由来

考虑到Java本身对日期时间的支持有限,并且Date和Calendar对象的并存导致各种方法使用混乱和复杂,故使用此工具类做了封装。这其中的封装主要是日期和字符串之间的转换,以及提供对日期的定位(一个月前等等)。
对于Date对象,为了便捷,使用了一个DateTime类来代替之,继承自Date对象,主要的便利在于,覆盖了toString()方法,返回yyyy-MM-dd HH:mm:ss形式的字符串,方便在输出时的调用(例如日志记录等),提供了众多便捷的方法对日期对象操作,关于DateTime会在相关章节介绍。

方法

转换

Date、long、Calendar之间的相互转换

  1. //当前时间
  2. Date date = DateUtil.date();
  3. //当前时间
  4. Date date2 = DateUtil.date(Calendar.getInstance());
  5. //当前时间
  6. Date date3 = DateUtil.date(System.currentTimeMillis());
  7. //当前时间字符串,格式:yyyy-MM-dd HH:mm:ss
  8. String now = DateUtil.now();
  9. //当前日期字符串,格式:yyyy-MM-dd
  10. String today= DateUtil.today();

字符串转日期

DateUtil.parse方法会自动识别一些常用格式,包括:

  1. yyyy-MM-dd HH:mm:ss
  2. yyyy-MM-dd
  3. HH:mm:ss
  4. yyyy-MM-dd HH:mm
  5. yyyy-MM-dd HH:mm:ss.SSS
    1. String dateStr = "2017-03-01";
    2. Date date = DateUtil.parse(dateStr);
    我们也可以使用自定义日期格式转化:
    1. String dateStr = "2017-03-01";
    2. Date date = DateUtil.parse(dateStr, "yyyy-MM-dd");

    格式化日期输出

    1. String dateStr = "2017-03-01";
    2. Date date = DateUtil.parse(dateStr);
    3. //结果 2017/03/01
    4. String format = DateUtil.format(date, "yyyy/MM/dd");
    5. //常用格式的格式化,结果:2017-03-01
    6. String formatDate = DateUtil.formatDate(date);
    7. //结果:2017-03-01 00:00:00
    8. String formatDateTime = DateUtil.formatDateTime(date);
    9. //结果:00:00:00
    10. String formatTime = DateUtil.formatTime(date);

    获取Date对象的某个部分

    1. Date date = DateUtil.date();
    2. //获得年的部分
    3. DateUtil.year(date);
    4. //获得月份,从0开始计数
    5. DateUtil.month(date);
    6. //获得月份枚举
    7. DateUtil.monthEnum(date);
    8. //.....

    开始和结束时间

    有的时候我们需要获得每天的开始时间、结束时间,每月的开始和结束时间等等,DateUtil也提供了相关方法:
    1. String dateStr = "2017-03-01 22:33:23";
    2. Date date = DateUtil.parse(dateStr);
    3. //一天的开始,结果:2017-03-01 00:00:00
    4. Date beginOfDay = DateUtil.beginOfDay(date);
    5. //一天的结束,结果:2017-03-01 23:59:59
    6. Date endOfDay = DateUtil.endOfDay(date);

    日期时间偏移

    日期或时间的偏移指针对某个日期增加或减少分、小时、天等等,达到日期变更的目的。Hutool也针对其做了大量封装
    1. String dateStr = "2017-03-01 22:33:23";
    2. Date date = DateUtil.parse(dateStr);
    3. //结果:2017-03-03 22:33:23
    4. Date newDate = DateUtil.offset(date, DateField.DAY_OF_MONTH, 2);
    5. //常用偏移,结果:2017-03-04 22:33:23
    6. DateTime newDate2 = DateUtil.offsetDay(date, 3);
    7. //常用偏移,结果:2017-03-01 19:33:23
    8. DateTime newDate3 = DateUtil.offsetHour(date, -3);
    针对当前时间,提供了简化的偏移方法(例如昨天、上周、上个月等):
    1. //昨天
    2. DateUtil.yesterday()
    3. //明天
    4. DateUtil.tomorrow()
    5. //上周
    6. DateUtil.lastWeek()
    7. //下周
    8. DateUtil.nextWeek()
    9. //上个月
    10. DateUtil.lastMonth()
    11. //下个月
    12. DateUtil.nextMonth()

    日期时间差

    有时候我们需要计算两个日期之间的时间差(相差天数、相差小时数等等),Hutool将此类方法封装为between方法:
    1. String dateStr1 = "2017-03-01 22:33:23";
    2. Date date1 = DateUtil.parse(dateStr1);
    3. String dateStr2 = "2017-04-01 23:33:23";
    4. Date date2 = DateUtil.parse(dateStr2);
    5. //相差一个月,31天
    6. long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);

    格式化时间差

    有时候我们希望看到易读的时间差,比如XX天XX小时XX分XX秒,此时使用DateUtil.formatBetween方法:
    1. //Level.MINUTE表示精确到分
    2. String formatBetween = DateUtil.formatBetween(between, Level.MINUTE);
    3. //输出:31天1小时
    4. Console.log(formatBetween);

    计时器

    计时器用于计算某段代码或过程花费的时间
    1. TimeInterval timer = DateUtil.timer();
    2. //---------------------------------
    3. //-------这是执行过程
    4. //---------------------------------
    5. timer.interval();//花费毫秒数
    6. timer.intervalRestart();//返回花费时间,并重置开始时间
    7. timer.intervalMinute();//花费分钟数

    其它

    1. //年龄
    2. DateUtil.ageOfNow("1990-01-30");
    3. //是否闰年
    4. DateUtil.isLeapYear(2017);

    日期时间对象-DateTime

    由来

    考虑工具类的局限性,在某些情况下使用并不简便,于是DateTime类诞生。DateTime对象充分吸取Joda-Time库的优点,并提供更多的便捷方法,这样我们在开发时不必再单独导入Joda-Time库便可以享受简单快速的日期时间处理过程。

    说明

    DateTime类继承于java.util.Date类,为Date类扩展了众多简便方法,这些方法多是DateUtil静态方法的对象表现形式,使用DateTime对象可以完全替代开发中Date对象的使用。

    使用

    新建对象

    DateTime对象包含众多的构造方法,构造方法支持的参数有:
  • Date
  • Calendar
  • String(日期字符串,第二个参数是日期格式)
  • long 毫秒数

构建对象有两种方式:DateTime.of()new DateTime()

  1. Date date = new Date();
  2. //new方式创建
  3. DateTime time = new DateTime(date);
  4. Console.log(time);
  5. //of方式创建
  6. DateTime now = DateTime.now();
  7. DateTime dt = DateTime.of(date);

使用对象

DateTime的成员方法与DateUtil中的静态方法所对应,因为是成员方法,因此可以使用更少的参数操作日期时间。
示例:获取日期成员(年、月、日等)

  1. DateTime dateTime = new DateTime("2017-01-05 12:34:23", DatePattern.NORM_DATETIME_FORMAT);
  2. //年,结果:2017
  3. int year = dateTime.year();
  4. //季度(非季节),结果:Season.SPRING
  5. Season season = dateTime.seasonEnum();
  6. //月份,结果:Month.JANUARY
  7. Month month = dateTime.monthEnum();
  8. //日,结果:5
  9. int day = dateTime.dayOfMonth();

更多成员方法请参阅API文档。

对象的可变性

DateTime对象默认是可变对象(调用offset、setField、setTime方法默认变更自身),但是这种可变性有时候会引起很多问题(例如多个地方共用DateTime对象)。我们可以调用setMutable(false)方法使其变为不可变对象。在不可变模式下,offsetsetField方法返回一个新对象,setTime方法抛出异常。

  1. DateTime dateTime = new DateTime("2017-01-05 12:34:23", DatePattern.NORM_DATETIME_FORMAT);
  2. //默认情况下DateTime为可变对象,此时offset == dateTime
  3. DateTime offset = dateTime.offset(DateField.YEAR, 0);
  4. //设置为不可变对象后变动将返回新对象,此时offset != dateTime
  5. dateTime.setMutable(false);
  6. offset = dateTime.offset(DateField.YEAR, 0);

格式化为字符串

调用toString()方法即可返回格式为yyyy-MM-dd HH:mm:ss的字符串,调用toString(String format)可以返回指定格式的字符串。

  1. DateTime dateTime = new DateTime("2017-01-05 12:34:23", DatePattern.NORM_DATETIME_FORMAT);
  2. //结果:2017-01-05 12:34:23
  3. String dateStr = dateTime.toString();
  4. //结果:2017/01/05

农历日期-ChineseDate

介绍

农历日期,提供了生肖、天干地支、传统节日等方法。

使用

  1. ChineseDate date = new ChineseDate(DateUtil.parseDate("2020-01-25"));
  2. // 一月
  3. date.getChineseMonth();
  4. // 正月
  5. date.getChineseMonthName();
  6. // 初一
  7. date.getChineseDay();
  8. // 庚子
  9. date.getCyclical();
  10. // 鼠
  11. date.getChineseZodiac();
  12. // 春节
  13. date.getFestivals();
  14. // 庚子鼠年 正月初一
  15. date.toString();