Hutool-core最新最全解析(一)

介绍

小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。官网

Hutool-all

Hutool的集成打包产品,由于考虑到“懒人”用户及分不清各个模块作用的用户,“无脑”引入hutool-all模块是快速开始和深入应用的最佳方式。
Maven

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.10</version>
</dependency>

Hutool-bom

Maven中的BOM

通过定义一整套相互兼容的jar包版本集合,使用时只需要依赖该BOM文件,无需再指定版本号。BOM维护方负责版本升级和jar包版本之间的兼容性,为了解决依赖冲突。让开发者更好的使用。

如何定义BOM

在POM文件只有这一部分定义后才能生效的,只需要在定义对外发布的客户端版本

import方式
// 在 properties标签指定版本号
<properties>
    <hutool.version>5.8.10</hutool.version>
</properties>
// 在dependencyManagement 引入父类pom 
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-bom</artifactId>
            <version>${hutool.version}</version>
            <type>pom</type> // 类型必须定义为pom
            <!-- 注意这里是import -->
            <scope>import</scope> // 局部导入
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
    // 只引入http 模块
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-http</artifactId>
    </dependency>
</dependencies>
exclude方式
// 在 properties标签指定版本号
<properties>
    <hutool.version>5.8.10</hutool.version>
</properties>
// 在dependencyManagement 引入父类pom 
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-bom</artifactId>
            <version>${hutool.version}</version>
            <type>pom</type> // 类型必须定义为pom
            // 排除
            <exclusions>
              <exclusion>
                    <groupId>cn.hutool</groupId>
                    <artifactId>hutool-system</artifactId>
              </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
    </dependency>
</dependencies>

Hutool-core

克隆

JDK中的Cloneable接口只是一个空接口,没有定义成员。指明一个类的实例化对象支持复制,如果不实现这个类调用对象的clone()方法就会抛出CloneNotSupportedException异常。clone()方法在Object对象中 返回值也是Object对象 克隆后强转类型。

泛型克隆接口 Cloneable

源码

package cn.hutool.core.clone;

public interface Cloneable<T> extends java.lang.Cloneable {
    T clone();
}

必须实现一个public的clone方法

package cn.importtest;

import cn.hutool.core.clone.CloneRuntimeException;
import cn.hutool.core.clone.Cloneable;

/**
 * TODO
 *
 * @author xsx
 * @date 2022/12/6 14:13
 */
public class ImportTest {

    public static void main(String[] args) {

        Cat cat  = new Cat();
        Cat newCar = cat.clone();
        System.out.println( newCar.toString() );
    }

    /**
     * 猫猫类,使用实现Cloneable方式
     * @author Looly
     *
     */
    private static class Cat implements Cloneable<Cat>{

        private String name = "miaomiao";
        private int age = 2;

        @Override
        public String toString() {
            return "Cat{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

        @Override
        public Cat clone() {
            try {
                return (Cat) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new CloneRuntimeException(e);
            }
        }
    }
}

泛型克隆类 CloneSupport

源码

package cn.hutool.core.clone;

public class CloneSupport<T> implements Cloneable<T> {
    public CloneSupport() {
    }

    public T clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException var2) {
            throw new CloneRuntimeException(var2);
        }
    }
}

帮你实现Cloneable接口中的clone方法 缺点 只能继承

package cn.importtest;

import cn.hutool.core.clone.CloneSupport;

/**
 * TODO
 *
 * @author xsx
 * @date 2022/12/6 14:13
 */
public class ImportTest {

    public static void main(String[] args) {

        Cat cat  = new Cat();
        Cat newCar = cat.clone();
        System.out.println( newCar.toString() );
    }

    /**
     * 猫猫类,使用实现Cloneable方式
     * @author Looly
     *
     */
    private static class Cat extends CloneSupport<Cat> {

        private String name = "miaomiao";
        private int age = 2;

        @Override
        public String toString() {
            return "Cat{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
}

类型转换

协议通信时 从HttpRequest获取的Parameter等等,有些数据需要转换,通常我们把数据先转成string 再调用其他方法,在此过程中 防止发生意外,不得不加上一层try catch

Convert类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package cn.hutool.core.convert;

import cn.hutool.core.convert.impl.CollectionConverter;
import cn.hutool.core.convert.impl.EnumConverter;
import cn.hutool.core.convert.impl.MapConverter;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.core.util.ByteUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class Convert {
    public Convert() {
    }
    // 转换成字符串 (可以填写默认值)
    public static String toStr(Object value, String defaultValue) {
        return (String)convertQuietly(String.class, value, defaultValue);
    }

    // 转换成字符串
    public static String toStr(Object value) {
        return toStr(value, (String)null);
    }
	// 转换成字符串数组
    public static String[] toStrArray(Object value) {
        return (String[])convert(String[].class, value);
    }
    // 转换成字符(填写默认值)
    public static Character toChar(Object value, Character defaultValue) {
        return (Character)convertQuietly(Character.class, value, defaultValue);
    }
    // 转换成字符
    public static Character toChar(Object value) {
        return toChar(value, (Character)null);
    }
 	// 转换成字符数组
    public static Character[] toCharArray(Object value) {
        return (Character[])convert(Character[].class, value);
    }
	// 转换成字节(填写默认值)
    public static Byte toByte(Object value, Byte defaultValue) {
        return (Byte)convertQuietly(Byte.class, value, defaultValue);
    }
	// 转换成字节
    public static Byte toByte(Object value) {
        return toByte(value, (Byte)null);
    }
	// 转换成字节数组
    public static Byte[] toByteArray(Object value) {
        return (Byte[])convert(Byte[].class, value);
    }
	// 转换成原始字节数组
    public static byte[] toPrimitiveByteArray(Object value) {
        return (byte[])convert(byte[].class, value);
    }
	// 转换成Short(填写默认值)
    public static Short toShort(Object value, Short defaultValue) {
        return (Short)convertQuietly(Short.class, value, defaultValue);
    }
	// 转换成Short
    public static Short toShort(Object value) {
        return toShort(value, (Short)null);
    }
	// 转换成Short数组
    public static Short[] toShortArray(Object value) {
        return (Short[])convert(Short[].class, value);
    }
	// 转换成数字(填写默认值)
    public static Number toNumber(Object value, Number defaultValue) {
        return (Number)convertQuietly(Number.class, value, defaultValue);
    }
    // 转换成数字
    public static Number toNumber(Object value) {
        return toNumber(value, (Number)null);
    }
	// 转换成数字数组
    public static Number[] toNumberArray(Object value) {
        return (Number[])convert(Number[].class, value);
    }
	// 转换成int类型(填写默认值)
    public static Integer toInt(Object value, Integer defaultValue) {
        return (Integer)convertQuietly(Integer.class, value, defaultValue);
    }
	// 转换成int类型
    public static Integer toInt(Object value) {
        return toInt(value, (Integer)null);
    }
	// 转换成int数组
    public static Integer[] toIntArray(Object value) {
        return (Integer[])convert(Integer[].class, value);
    }
	// 转换成Long(填写默认值)
    public static Long toLong(Object value, Long defaultValue) {
        return (Long)convertQuietly(Long.class, value, defaultValue);
    }
	// 转换成Long
    public static Long toLong(Object value) {
        return toLong(value, (Long)null);
    }
	// 转换成Long数组
    public static Long[] toLongArray(Object value) {
        return (Long[])convert(Long[].class, value);
    }
	// 转换成Double(填写默认值)
    public static Double toDouble(Object value, Double defaultValue) {
        return (Double)convertQuietly(Double.class, value, defaultValue);
    }
	// 转换成Double
    public static Double toDouble(Object value) {
        return toDouble(value, (Double)null);
    }
	// 转换成Double数组
    public static Double[] toDoubleArray(Object value) {
        return (Double[])convert(Double[].class, value);
    }
	// 转换成Float(填写默认值)
    public static Float toFloat(Object value, Float defaultValue) {
        return (Float)convertQuietly(Float.class, value, defaultValue);
    }
	// 转换成Float
    public static Float toFloat(Object value) {
        return toFloat(value, (Float)null);
    }
	// 转换成Float数组
    public static Float[] toFloatArray(Object value) {
        return (Float[])convert(Float[].class, value);
    }
	// 转换成Boolean(填写默认值)
    public static Boolean toBool(Object value, Boolean defaultValue) {
        return (Boolean)convertQuietly(Boolean.class, value, defaultValue);
    }
	// 转换成Boolean
    public static Boolean toBool(Object value) {
        return toBool(value, (Boolean)null);
    }
	// 转换成Boolean数组
    public static Boolean[] toBooleanArray(Object value) {
        return (Boolean[])convert(Boolean[].class, value);
    }
	// 转换成BigInteger(填写默认值)
    public static BigInteger toBigInteger(Object value, BigInteger defaultValue) {
        return (BigInteger)convertQuietly(BigInteger.class, value, defaultValue);
    }
	// 转换成BigInteger
    public static BigInteger toBigInteger(Object value) {
        return toBigInteger(value, (BigInteger)null);
    }
	// 转换成BigDecimal(填写默认值)
    public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {
        return (BigDecimal)convertQuietly(BigDecimal.class, value, defaultValue);
    }
	// 转换成BigDecimal
    public static BigDecimal toBigDecimal(Object value) {
        return toBigDecimal(value, (BigDecimal)null);
    }
	// 转换成Date(填写默认值)
    public static Date toDate(Object value, Date defaultValue) {
        return (Date)convertQuietly(Date.class, value, defaultValue);
    }
	// 转换成LocalDateTime(填写默认值)
    public static LocalDateTime toLocalDateTime(Object value, LocalDateTime defaultValue) {
        return (LocalDateTime)convertQuietly(LocalDateTime.class, value, defaultValue);
    }
	// 转换成LocalDateTime
    public static LocalDateTime toLocalDateTime(Object value) {
        return toLocalDateTime(value, (LocalDateTime)null);
    }
	// 转换成Date(填写默认值)
    public static Date toInstant(Object value, Date defaultValue) {
        return (Date)convertQuietly(Instant.class, value, defaultValue);
    }
	// 转换成Date
    public static Date toDate(Object value) {
        return toDate(value, (Date)null);
    }
	// 转换成Enum(填写默认值)
    public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue) {
        return (Enum)(new EnumConverter(clazz)).convertQuietly(value, defaultValue);
    }
	// 转换成Enum
    public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value) {
        return toEnum(clazz, value, (Enum)null);
    }
   // 转换成Collection类
    public static Collection<?> toCollection(Class<?> collectionType, Class<?> elementType, Object value) {
        return (new CollectionConverter(collectionType, elementType)).convert(value, (Collection)null);
    }
   // 转换成List列表
    public static List<?> toList(Object value) {
        return (List)convert(List.class, value);
    }
   // 转换成ArrayListList列表
    public static <T> List<T> toList(Class<T> elementType, Object value) {
        return (List)toCollection(ArrayList.class, elementType, value);
    }
   // 转换成HashSet列表
    public static <T> Set<T> toSet(Class<T> elementType, Object value) {
        return (Set)toCollection(HashSet.class, elementType, value);
    }
 	// 转换成HashMap或者指定keyValue键值对
    public static <K, V> Map<K, V> toMap(Class<K> keyType, Class<V> valueType, Object value) {
        return value instanceof Map ? toMap(value.getClass(), keyType, valueType, value) : toMap(HashMap.class, keyType, valueType, value);
    }
 	// 转换成Map的keyValue键值对
    public static <K, V> Map<K, V> toMap(Class<? extends Map> mapType, Class<K> keyType, Class<V> valueType, Object value) {
        return (Map)(new MapConverter(mapType, keyType, valueType)).convert(value, (Object)null);
    }

    // <T> T 返回值是一个类型 第二个T 代表告诉编辑器 传递什么返回什么 
 	// 通过对象名字转换成指定的class对象
    public static <T> T convertByClassName(String className, Object value) throws ConvertException {
        return convert(ClassUtil.loadClass(className), value);
    }

    // Class<T> 代表这个类型所对应的类
 	// 转换成指定的class对象
    public static <T> T convert(Class<T> type, Object value) throws ConvertException {
        return convert((Type)type, value);
    }
 	// 转换成指定文件类型
    public static <T> T convert(TypeReference<T> reference, Object value) throws ConvertException {
        return convert((Type)reference.getType(), value, (Object)null);
    }
 	// 指定类型名字转换成指定类型
    public static <T> T convert(Type type, Object value) throws ConvertException {
        return convert((Type)type, value, (Object)null);
    }
    // 转换成泛型类(填写类型)
    public static <T> T convert(Class<T> type, Object value, T defaultValue) throws ConvertException {
        return convert((Type)type, value, defaultValue);
    }
    // 转换成泛型类(填写类型)
    public static <T> T convert(Type type, Object value, T defaultValue) throws ConvertException {
        return convertWithCheck(type, value, defaultValue, false);
    }
    // 转换成泛型
    public static <T> T convertQuietly(Type type, Object value) {
        return convertQuietly(type, value, (Object)null);
    }
    // 转换成泛型
    public static <T> T convertQuietly(Type type, Object value, T defaultValue) {
        return convertWithCheck(type, value, defaultValue, true);
    }

    public static <T> T convertWithCheck(Type type, Object value, T defaultValue, boolean quietly) {
        ConverterRegistry registry = ConverterRegistry.getInstance();

        try {
            return registry.convert(type, value, defaultValue);
        } catch (Exception var6) {
            if (quietly) {
                return defaultValue;
            } else {
                throw var6;
            }
        }
    }

    // 半角转全角
    public static String toSBC(String input) {
        return toSBC(input, (Set)null);
    }

    public static String toSBC(String input, Set<Character> notConvertSet) {
        if (StrUtil.isEmpty(input)) {
            return input;
        } else {
            char[] c = input.toCharArray();

            for(int i = 0; i < c.length; ++i) {
                if (null == notConvertSet || !notConvertSet.contains(c[i])) {
                    if (c[i] == ' ') {
                        c[i] = 12288;
                    } else if (c[i] < 127) {
                        c[i] += 'ﻠ';
                    }
                }
            }

            return new String(c);
        }
    }
    
    // 全角转半角
    public static String toDBC(String input) {
        return toDBC(input, (Set)null);
    }

    public static String toDBC(String text, Set<Character> notConvertSet) {
        if (StrUtil.isBlank(text)) {
            return text;
        } else {
            char[] c = text.toCharArray();

            for(int i = 0; i < c.length; ++i) {
                if (null == notConvertSet || !notConvertSet.contains(c[i])) {
                    if (c[i] != 12288 && c[i] != 160 && c[i] != 8199 && c[i] != 8239) {
                        if (c[i] > '\uff00' && c[i] < '⦅') {
                            c[i] -= 'ﻠ';
                        }
                    } else {
                        c[i] = ' ';
                    }
                }
            }

            return new String(c);
        }
    }

    // 转为16进制(Hex)字符串 (填写字符编码)
    public static String toHex(String str, Charset charset) {
        return HexUtil.encodeHexStr(str, charset);
    }
    
    // 转为16进制(Hex)字符串
    public static String toHex(byte[] bytes) {
        return HexUtil.encodeHexStr(bytes);
    }
    // 16进制转为byte[]
    public static byte[] hexToBytes(String src) {
        return HexUtil.decodeHex(src.toCharArray());
    }
     // 16进制转为byte[]
    public static String hexToStr(String hexStr, Charset charset) {
        return HexUtil.decodeHexStr(hexStr, charset);
    }
     // 字符串转Unicode
    public static String strToUnicode(String strText) {
        return UnicodeUtil.toUnicode(strText);
    }
     // Unicode转字符串
    public static String unicodeToStr(String unicode) {
        return UnicodeUtil.toString(unicode);
    }
    // 原始编码转码指定编码
    public static String convertCharset(String str, String sourceCharset, String destCharset) {
        return StrUtil.hasBlank(new CharSequence[]{str, sourceCharset, destCharset}) ? str : CharsetUtil.convert(str, sourceCharset, destCharset);
    }
    // 原始时间单位转码指定时间单位
    public static long convertTime(long sourceDuration, TimeUnit sourceUnit, TimeUnit destUnit) {
        Assert.notNull(sourceUnit, "sourceUnit is null !", new Object[0]);
        Assert.notNull(destUnit, "destUnit is null !", new Object[0]);
        return destUnit.convert(sourceDuration, sourceUnit);
    }
    // 包装类和原始类相互转换 去包装
    public static Class<?> wrap(Class<?> clazz) {
        return BasicType.wrap(clazz);
    }
    // 包装类和原始类相互转换 包装
    public static Class<?> unWrap(Class<?> clazz) {
        return BasicType.unWrap(clazz);
    }
    // 数字转为英文表达
    public static String numberToWord(Number number) {
        return NumberWordFormatter.format(number);
    }
    // 数字简化
    public static String numberToSimple(Number number) {
        return NumberWordFormatter.formatSimple(number.longValue());
    }
    // 数字转中文
    public static String numberToChinese(double number, boolean isUseTraditional) {
        return NumberChineseFormatter.format(number, isUseTraditional);
    }
    // 中文转数字
    public static int chineseToNumber(String number) {
        return NumberChineseFormatter.chineseToNumber(number);
    }
    // 金额大小写转换
    public static String digitToChinese(Number n) {
        return null == n ? "零" : NumberChineseFormatter.format(n.doubleValue(), true, true);
    }
    // 中国货币数量
    public static BigDecimal chineseMoneyToNumber(String chineseMoneyAmount) {
        return NumberChineseFormatter.chineseMoneyToNumber(chineseMoneyAmount);
    }
   // int 转 byte
    public static byte intToByte(int intValue) {
        return (byte)intValue;
    }
   // 字节转换为无符号整型
    public static int byteToUnsignedInt(byte byteValue) {
        return byteValue & 255;
    }
   // 字节数组转换为Short
    public static short bytesToShort(byte[] bytes) {
        return ByteUtil.bytesToShort(bytes);
    }
   // Short转换为字节数组
    public static byte[] shortToBytes(short shortValue) {
        return ByteUtil.shortToBytes(shortValue);
    }
   // 字节数组转换为int
    public static int bytesToInt(byte[] bytes) {
        return ByteUtil.bytesToInt(bytes);
    }
   // int转换为字节数组
    public static byte[] intToBytes(int intValue) {
        return ByteUtil.intToBytes(intValue);
    }
   // 字节数组转换为long
    public static byte[] longToBytes(long longValue) {
        return ByteUtil.longToBytes(longValue);
    }
   // long转换为字节数组
    public static long bytesToLong(byte[] bytes) {
        return ByteUtil.bytesToLong(bytes);
    }
}

日期时间

提供针对JDK中Date和Calendar对象的封装

日期时间工具

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package cn.hutool.core.date;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.date.BetweenFormatter.Level;
import cn.hutool.core.date.format.DateParser;
import cn.hutool.core.date.format.DatePrinter;
import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.Year;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Locale.Category;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class DateUtil extends CalendarUtil {
    private static final String[] wtb = new String[]{"sun", "mon", "tue", "wed", "thu", "fri", "sat", "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec", "gmt", "ut", "utc", "est", "edt", "cst", "cdt", "mst", "mdt", "pst", "pdt"};

    public DateUtil() {
    }
   // 返回当前最新DateTime
    public static DateTime date() {
        return new DateTime();
    }
   // 返回当前精确到秒最新DateTime
    public static DateTime dateSecond() {
        return beginOfSecond(date());
    }
   // 返回当前DateTime
    public static DateTime date(Date date) {
        return date instanceof DateTime ? (DateTime)date : dateNew(date);
    }
   // 返回当前最新DateTime
    public static DateTime dateNew(Date date) {
        return new DateTime(date);
    }
   // 通过时间戳返回当前DateTime
    public static DateTime date(long date) {
        return new DateTime(date);
    }
   // 通过日历返回当前DateTime
    public static DateTime date(Calendar calendar) {
        return new DateTime(calendar);
    }
    // 通过格式化器返回当前DateTime
    public static DateTime date(TemporalAccessor temporalAccessor) {
        return new DateTime(temporalAccessor);
    }
    // 返回毫秒时间戳
    public static long current() {
        return System.currentTimeMillis();
    }
    // 返回秒时间戳
    public static long currentSeconds() {
        return System.currentTimeMillis() / 1000L;
    }
    // 返回格式化时间字符串
    public static String now() {
        return formatDateTime(new DateTime());
    }
    // 返回格式化时间字符串
    public static String today() {
        return formatDate(new DateTime());
    }
    // 返回第几季度(3个月一个季度)数字
    public static int year(Date date) {
        return DateTime.of(date).year();
    }
    // 返回第几季度(3个月一个季度)文字
    public static int quarter(Date date) {
        return DateTime.of(date).quarter();
    }
    // 获得指定日期所属季度
    public static Quarter quarterEnum(Date date) {
        return DateTime.of(date).quarterEnum();
    }
    // 获得当前月份
    public static int month(Date date) {
        return DateTime.of(date).month();
    }
    // 获得月份枚举
    public static Month monthEnum(Date date) {
        return DateTime.of(date).monthEnum();
    }
     // 获得指定日期是所在年份的第几周
    public static int weekOfYear(Date date) {
        return DateTime.of(date).weekOfYear();
    }
     // 获得指定日期是所在月份的第几周
    public static int weekOfMonth(Date date) {
        return DateTime.of(date).weekOfMonth();
    }
   // 获得指定日期是所在月份的第几天
    public static int dayOfMonth(Date date) {
        return DateTime.of(date).dayOfMonth();
    }
   // 获得指定日期是所在年份的第几天
    public static int dayOfYear(Date date) {
        return DateTime.of(date).dayOfYear();
    }
   // 获得指定日期是所在周的第几天
    public static int dayOfWeek(Date date) {
        return DateTime.of(date).dayOfWeek();
    }
   // 获得指定日期是所在星期的第几天枚举
    public static Week dayOfWeekEnum(Date date) {
        return DateTime.of(date).dayOfWeekEnum();
    }
   // 获得指定日期是否是周末
    public static boolean isWeekend(Date date) {
        Week week = dayOfWeekEnum(date);
        return Week.SATURDAY == week || Week.SUNDAY == week;
    }
   // 获得指定日期获取小时
    public static int hour(Date date, boolean is24HourClock) {
        return DateTime.of(date).hour(is24HourClock);
    }
   // 获得指定日期获取分钟
    public static int minute(Date date) {
        return DateTime.of(date).minute();
    }
   // 获得指定日期获取秒
    public static int second(Date date) {
        return DateTime.of(date).second();
    }
   // 获得指定日期获取毫秒
    public static int millisecond(Date date) {
        return DateTime.of(date).millisecond();
    }
   // 获得指定日期是否上午
    public static boolean isAM(Date date) {
        return DateTime.of(date).isAM();
    }
   // 获得指定日期是否下午
    public static boolean isPM(Date date) {
        return DateTime.of(date).isPM();
    }
    // 今年
    public static int thisYear() {
        return year(date());
    }
    // 当前月份
    public static int thisMonth() {
        return month(date());
    }
    // 当前月份枚举
    public static Month thisMonthEnum() {
        return monthEnum(date());
    }
    // 当前日期所在年份的第几周
    public static int thisWeekOfYear() {
        return weekOfYear(date());
    }
    // 当前日期所在月份的第几周
    public static int thisWeekOfMonth() {
        return weekOfMonth(date());
    }
    // 当前日期所在月份的第几天
    public static int thisDayOfMonth() {
        return dayOfMonth(date());
    }
    // 当前日期是星期几
    public static int thisDayOfWeek() {
        return dayOfWeek(date());
    }
    // 当前日期是星期几枚举
    public static Week thisDayOfWeekEnum() {
        return dayOfWeekEnum(date());
    }
    // 当前日期的小时数部分 是否24小时制
    public static int thisHour(boolean is24HourClock) {
        return hour(date(), is24HourClock);
    }
    // 当前日期的分钟数部分
    public static int thisMinute() {
        return minute(date());
    }
    // 当前日期的秒数部分
    public static int thisSecond() {
        return second(date());
    }
    // 当前日期的毫秒数部分
    public static int thisMillisecond() {
        return millisecond(date());
    }
	// 获得指定日期年份和季节字符串
    public static String yearAndQuarter(Date date) {
        return yearAndQuarter(calendar(date));
    }
	// 获得指定日期年份和季节 Set字符串
    public static LinkedHashSet<String> yearAndQuarter(Date startDate, Date endDate) {
        return startDate != null && endDate != null ? yearAndQuarter(startDate.getTime(), endDate.getTime()) : new LinkedHashSet(0);
    }
	// 格式化日期时间<br> 格式 yyyy-MM-dd HH:mm:ss
    public static String formatLocalDateTime(LocalDateTime localDateTime) {
        return LocalDateTimeUtil.formatNormal(localDateTime);
    }
	// 根据特定格式格式化日期
    public static String format(LocalDateTime localDateTime, String format) {
        return LocalDateTimeUtil.format(localDateTime, format);
    }
	// 根据特定格式格式化日期
    public static String format(Date date, String format) {
        if (null != date && !StrUtil.isBlank(format)) {
            if (GlobalCustomFormat.isCustomFormat(format)) {
                return GlobalCustomFormat.format(date, format);
            } else {
                TimeZone timeZone = null;
                if (date instanceof DateTime) {
                    timeZone = ((DateTime)date).getTimeZone();
                }

                return format((Date)date, (DateFormat)newSimpleFormat(format, (Locale)null, timeZone));
            }
        } else {
            return null;
        }
    }
	// 根据特定格式格式化日期
    public static String format(Date date, DatePrinter format) {
        return null != format && null != date ? format.format(date) : null;
    }
	// 根据特定格式格式化日期
    public static String format(Date date, DateFormat format) {
        return null != format && null != date ? format.format(date) : null;
    }
	// 根据特定格式格式化日期
    public static String format(Date date, DateTimeFormatter format) {
        return null != format && null != date ? TemporalAccessorUtil.format(date.toInstant(), format) : null;
    }
	// 格式化日期时间<br> 格式 yyyy-MM-dd HH:mm:ss
    public static String formatDateTime(Date date) {
        return null == date ? null : DatePattern.NORM_DATETIME_FORMAT.format(date);
    }
	// 格式化日期部分(不包括时间)<br> 格式 yyyy-MM-dd
    public static String formatDate(Date date) {
        return null == date ? null : DatePattern.NORM_DATE_FORMAT.format(date);
    }
	// 格式化日期部分(不包括时间)<br> 格式 HH:mm:ss
    public static String formatTime(Date date) {
        return null == date ? null : DatePattern.NORM_TIME_FORMAT.format(date);
    }
	// 格式化日期部分(不包括时间)<br> 格式  dd MMM yyyy HH:mm:ss z
    public static String formatHttpDate(Date date) {
        return null == date ? null : DatePattern.HTTP_DATETIME_FORMAT.format(date);
    }
	// 格式化为中文日期格式,如果isUppercase为false,则返回类似:2018年10月24日,否则返回二〇一八年十月二十四日
    public static String formatChineseDate(Date date, boolean isUppercase, boolean withTime) {
        if (null == date) {
            return null;
        } else {
            return !isUppercase ? (withTime ? DatePattern.CHINESE_DATE_TIME_FORMAT : DatePattern.CHINESE_DATE_FORMAT).format(date) : CalendarUtil.formatChineseDate(CalendarUtil.calendar(date), withTime);
        }
    }
    // 构建LocalDateTime对象格式:yyyy-MM-dd HH:mm:ss
    public static LocalDateTime parseLocalDateTime(CharSequence dateStr) {
        return parseLocalDateTime(dateStr, "yyyy-MM-dd HH:mm:ss");
    }
    // 构建LocalDateTime对象
    public static LocalDateTime parseLocalDateTime(CharSequence dateStr, String format) {
        return LocalDateTimeUtil.parse(dateStr, format);
    }
    // 构建DateTime对象
    public static DateTime parse(CharSequence dateStr, DateFormat dateFormat) {
        return new DateTime(dateStr, dateFormat);
    }
    // 构建DateTime对象
    public static DateTime parse(CharSequence dateStr, DateParser parser) {
        return new DateTime(dateStr, parser);
    }
    // 构建DateTime对象
    public static DateTime parse(CharSequence dateStr, DateParser parser, boolean lenient) {
        return new DateTime(dateStr, parser, lenient);
    }
    // 构建DateTime对象
    public static DateTime parse(CharSequence dateStr, DateTimeFormatter formatter) {
        return new DateTime(dateStr, formatter);
    }
    // 构建DateTime对象
    public static DateTime parse(CharSequence dateStr, String format) {
        return new DateTime(dateStr, format);
    }
    // 构建DateTime对象
    public static DateTime parse(CharSequence dateStr, String format, Locale locale) {
        return GlobalCustomFormat.isCustomFormat(format) ? new DateTime(GlobalCustomFormat.parse(dateStr, format)) : new DateTime(dateStr, newSimpleFormat(format, locale, (TimeZone)null));
    }
    // 构建DateTime对象
    public static DateTime parse(String str, String... parsePatterns) throws DateException {
        return new DateTime(CalendarUtil.parseByPatterns(str, parsePatterns));
    }
    // 构建DateTime对象(yyyy-MM-dd HH:mm:ss)
    public static DateTime parseDateTime(CharSequence dateString) {
        CharSequence dateString = normalize(dateString);
        return parse((CharSequence)dateString, (DateParser)DatePattern.NORM_DATETIME_FORMAT);
    }
    // 构建DateTime对象(yyyy-MM-dd)
    public static DateTime parseDate(CharSequence dateString) {
        CharSequence dateString = normalize(dateString);
        return parse((CharSequence)dateString, (DateParser)DatePattern.NORM_DATE_FORMAT);
    }
    // 构建DateTime对象(HH:mm:ss)
    public static DateTime parseTime(CharSequence timeString) {
        CharSequence timeString = normalize(timeString);
        return parse((CharSequence)timeString, (DateParser)DatePattern.NORM_TIME_FORMAT);
    }
    // 解析时间,格式HH:mm 或 HH:mm:ss,日期默认为今天
    public static DateTime parseTimeToday(CharSequence timeString) {
        CharSequence timeString = StrUtil.format("{} {}", new Object[]{today(), timeString});
        return 1 == StrUtil.count(timeString, ':') ? parse((CharSequence)timeString, (String)"yyyy-MM-dd HH:mm") : parse((CharSequence)timeString, (DateParser)DatePattern.NORM_DATETIME_FORMAT);
    }
   // 解析UTC时间,格式:yyyy-MM-dd’T’HH:mm:ss’Z’yyyy-MM-dd’T’HH:mm:ss.SSS’Z’yyyy-MM-dd’T’HH:mm:ssZ yyyy-MM-dd’T’HH:mm:ss.SSSZ
    public static DateTime parseUTC(String utcString) {
        if (utcString == null) {
            return null;
        } else {
            int length = utcString.length();
            if (StrUtil.contains(utcString, 'Z')) {
                if (length == "yyyy-MM-dd'T'HH:mm:ss'Z'".length() - 4) {
                    return parse((CharSequence)utcString, (DateParser)DatePattern.UTC_FORMAT);
                }

                int patternLength = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'".length();
                if (length <= patternLength - 4 && length >= patternLength - 6) {
                    return parse((CharSequence)utcString, (DateParser)DatePattern.UTC_MS_FORMAT);
                }
            } else {
                if (StrUtil.contains(utcString, '+')) {
                    utcString = utcString.replace(" +", "+");
                    String zoneOffset = StrUtil.subAfter(utcString, '+', true);
                    if (StrUtil.isBlank(zoneOffset)) {
                        throw new DateException("Invalid format: [{}]", new Object[]{utcString});
                    }

                    if (!StrUtil.contains(zoneOffset, ':')) {
                        String pre = StrUtil.subBefore(utcString, '+', true);
                        utcString = pre + "+" + zoneOffset.substring(0, 2) + ":00";
                    }

                    if (StrUtil.contains(utcString, '.')) {
                        return parse((CharSequence)utcString, (DateParser)DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
                    }

                    return parse((CharSequence)utcString, (DateParser)DatePattern.UTC_WITH_XXX_OFFSET_FORMAT);
                }

                if (ReUtil.contains("-\\d{2}:?00", utcString)) {
                    utcString = utcString.replace(" -", "-");
                    if (':' != utcString.charAt(utcString.length() - 3)) {
                        utcString = utcString.substring(0, utcString.length() - 2) + ":00";
                    }

                    if (StrUtil.contains(utcString, '.')) {
                        return new DateTime(utcString, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
                    }

                    return new DateTime(utcString, DatePattern.UTC_WITH_XXX_OFFSET_FORMAT);
                }

                if (length == "yyyy-MM-dd'T'HH:mm:ss".length() - 2) {
                    return parse((CharSequence)utcString, (DateParser)DatePattern.UTC_SIMPLE_FORMAT);
                }

                if (length == "yyyy-MM-dd'T'HH:mm:ss".length() - 5) {
                    return parse((CharSequence)(utcString + ":00"), (DateParser)DatePattern.UTC_SIMPLE_FORMAT);
                }

                if (StrUtil.contains(utcString, '.')) {
                    return parse((CharSequence)utcString, (DateParser)DatePattern.UTC_SIMPLE_MS_FORMAT);
                }
            }

            throw new DateException("No format fit for date String [{}] !", new Object[]{utcString});
        }
    }
   // 解析CST时间,格式:EEE MMM dd HH:mm:ss z yyyy(例如:Wed Aug 01 00:00:00 CST 2012)
    public static DateTime parseCST(CharSequence cstString) {
        return cstString == null ? null : parse((CharSequence)cstString, (DateParser)DatePattern.JDK_DATETIME_FORMAT);
    }
  // 将日期字符串转换为{@link DateTime}对象
    public static DateTime parse(CharSequence dateCharSequence) {
        if (StrUtil.isBlank(dateCharSequence)) {
            return null;
        } else {
            String dateStr = dateCharSequence.toString();
            dateStr = StrUtil.removeAll(dateStr.trim(), new char[]{'日', '秒'});
            int length = dateStr.length();
            if (NumberUtil.isNumber(dateStr)) {
                if (length == "yyyyMMddHHmmss".length()) {
                    return parse((CharSequence)dateStr, (DateParser)DatePattern.PURE_DATETIME_FORMAT);
                }

                if (length == "yyyyMMddHHmmssSSS".length()) {
                    return parse((CharSequence)dateStr, (DateParser)DatePattern.PURE_DATETIME_MS_FORMAT);
                }

                if (length == "yyyyMMdd".length()) {
                    return parse((CharSequence)dateStr, (DateParser)DatePattern.PURE_DATE_FORMAT);
                }

                if (length == "HHmmss".length()) {
                    return parse((CharSequence)dateStr, (DateParser)DatePattern.PURE_TIME_FORMAT);
                }
            } else {
                if (ReUtil.isMatch(PatternPool.TIME, dateStr)) {
                    return parseTimeToday(dateStr);
                }

                if (StrUtil.containsAnyIgnoreCase(dateStr, wtb)) {
                    return parseCST(dateStr);
                }

                if (StrUtil.contains(dateStr, 'T')) {
                    return parseUTC(dateStr);
                }
            }

            dateStr = normalize(dateStr);
            if (ReUtil.isMatch(DatePattern.REGEX_NORM, dateStr)) {
                int colonCount = StrUtil.count(dateStr, ':');
                switch(colonCount) {
                case 0:
                    return parse((CharSequence)dateStr, (DateParser)DatePattern.NORM_DATE_FORMAT);
                case 1:
                    return parse((CharSequence)dateStr, (DateParser)DatePattern.NORM_DATETIME_MINUTE_FORMAT);
                case 2:
                    int indexOfDot = StrUtil.indexOf(dateStr, '.');
                    if (indexOfDot > 0) {
                        int length1 = dateStr.length();
                        if (length1 - indexOfDot > 4) {
                            dateStr = StrUtil.subPre(dateStr, indexOfDot + 4);
                        }

                        return parse((CharSequence)dateStr, (DateParser)DatePattern.NORM_DATETIME_MS_FORMAT);
                    }

                    return parse((CharSequence)dateStr, (DateParser)DatePattern.NORM_DATETIME_FORMAT);
                }
            }

            throw new DateException("No format fit for date String [{}] !", new Object[]{dateStr});
        }
    }
 	// 修改日期为某个时间字段起始时间
    public static DateTime truncate(Date date, DateField dateField) {
        return new DateTime(truncate(calendar(date), dateField));
    }
	// 修改日期为某个时间字段四舍五入时间
    public static DateTime round(Date date, DateField dateField) {
        return new DateTime(round(calendar(date), dateField));
    }
	// 修改日期为某个时间字段结束时间
    public static DateTime ceiling(Date date, DateField dateField) {
        return new DateTime(ceiling(calendar(date), dateField));
    }
	// 修改日期为某个时间字段结束时间
    public static DateTime ceiling(Date date, DateField dateField, boolean truncateMillisecond) {
        return new DateTime(ceiling(calendar(date), dateField, truncateMillisecond));
    }
 	// 获取秒级别的开始时间,即忽略毫秒部分
    public static DateTime beginOfSecond(Date date) {
        return new DateTime(beginOfSecond(calendar(date)));
    }
	// 获取秒级别的结束时间,即毫秒设置为999
    public static DateTime endOfSecond(Date date) {
        return new DateTime(endOfSecond(calendar(date)));
    }
	// 获取某小时的开始时间
    public static DateTime beginOfHour(Date date) {
        return new DateTime(beginOfHour(calendar(date)));
    }
	// 获取某小时的结束时间
    public static DateTime endOfHour(Date date) {
        return new DateTime(endOfHour(calendar(date)));
    }
	// 获取某分钟的开始时间
    public static DateTime beginOfMinute(Date date) {
        return new DateTime(beginOfMinute(calendar(date)));
    }
	// 获取某分钟的结束时间
    public static DateTime endOfMinute(Date date) {
        return new DateTime(endOfMinute(calendar(date)));
    }
	// 获取某天的开始时间
    public static DateTime beginOfDay(Date date) {
        return new DateTime(beginOfDay(calendar(date)));
    }
	// 获取某天的结束时间
    public static DateTime endOfDay(Date date) {
        return new DateTime(endOfDay(calendar(date)));
    }
	// 获取某周的开始时间,周一定为一周的开始时间
    public static DateTime beginOfWeek(Date date) {
        return new DateTime(beginOfWeek(calendar(date)));
    }
	// 获取某周的开始时间
    public static DateTime beginOfWeek(Date date, boolean isMondayAsFirstDay) {
        return new DateTime(beginOfWeek(calendar(date), isMondayAsFirstDay));
    }
	// 获取某周的结束时间,周日定为一周的结束
    public static DateTime endOfWeek(Date date) {
        return new DateTime(endOfWeek(calendar(date)));
    }
	// 获取某周的结束时间
    public static DateTime endOfWeek(Date date, boolean isSundayAsLastDay) {
        return new DateTime(endOfWeek(calendar(date), isSundayAsLastDay));
    }
	// 获取某月的开始时间
    public static DateTime beginOfMonth(Date date) {
        return new DateTime(beginOfMonth(calendar(date)));
    }
	// 获取某月的结束时间
    public static DateTime endOfMonth(Date date) {
        return new DateTime(endOfMonth(calendar(date)));
    }
	// 获取某季度的开始时间
    public static DateTime beginOfQuarter(Date date) {
        return new DateTime(beginOfQuarter(calendar(date)));
    }
	// 获取某季度的结束时间
    public static DateTime endOfQuarter(Date date) {
        return new DateTime(endOfQuarter(calendar(date)));
    }
	// 获取某年的开始时间
    public static DateTime beginOfYear(Date date) {
        return new DateTime(beginOfYear(calendar(date)));
    }
	// 获取某年的结束时间
    public static DateTime endOfYear(Date date) {
        return new DateTime(endOfYear(calendar(date)));
    }
	// 昨天
    public static DateTime yesterday() {
        return offsetDay(new DateTime(), -1);
    }
	// 明天
    public static DateTime tomorrow() {
        return offsetDay(new DateTime(), 1);
    }
	// 上周
    public static DateTime lastWeek() {
        return offsetWeek(new DateTime(), -1);
    }
	// 下周
    public static DateTime nextWeek() {
        return offsetWeek(new DateTime(), 1);
    }
	// 上个月
    public static DateTime lastMonth() {
        return offsetMonth(new DateTime(), -1);
    }
	// 下个月
    public static DateTime nextMonth() {
        return offsetMonth(new DateTime(), 1);
    }
	// 偏移毫秒数
    public static DateTime offsetMillisecond(Date date, int offset) {
        return offset(date, DateField.MILLISECOND, offset);
    }
	// 偏移秒数
    public static DateTime offsetSecond(Date date, int offset) {
        return offset(date, DateField.SECOND, offset);
    }
	// 偏移分钟
    public static DateTime offsetMinute(Date date, int offset) {
        return offset(date, DateField.MINUTE, offset);
    }
	// 偏移小时
    public static DateTime offsetHour(Date date, int offset) {
        return offset(date, DateField.HOUR_OF_DAY, offset);
    }
	// 偏移天
    public static DateTime offsetDay(Date date, int offset) {
        return offset(date, DateField.DAY_OF_YEAR, offset);
    }
	// 偏移周
    public static DateTime offsetWeek(Date date, int offset) {
        return offset(date, DateField.WEEK_OF_YEAR, offset);
    }
	// 偏移月
    public static DateTime offsetMonth(Date date, int offset) {
        return offset(date, DateField.MONTH, offset);
    }
	// 获取指定日期偏移指定时间后的时间,生成的偏移日期不影响原日期
    public static DateTime offset(Date date, DateField dateField, int offset) {
        return dateNew(date).offset(dateField, offset);
    }
	// 判断两个日期相差的时长,只保留绝对值
    public static long between(Date beginDate, Date endDate, DateUnit unit) {
        return between(beginDate, endDate, unit, true);
    }
	// 判断两个日期相差的时长
    public static long between(Date beginDate, Date endDate, DateUnit unit, boolean isAbs) {
        return (new DateBetween(beginDate, endDate, isAbs)).between(unit);
    }
	// 判断两个日期相差的毫秒数
    public static long betweenMs(Date beginDate, Date endDate) {
        return (new DateBetween(beginDate, endDate)).between(DateUnit.MS);
    }
	// 判断两个日期相差的天数
    public static long betweenDay(Date beginDate, Date endDate, boolean isReset) {
        if (isReset) {
            beginDate = beginOfDay((Date)beginDate);
            endDate = beginOfDay((Date)endDate);
        }

        return between((Date)beginDate, (Date)endDate, DateUnit.DAY);
    }
	// 计算指定指定时间区间内的周数
    public static long betweenWeek(Date beginDate, Date endDate, boolean isReset) {
        if (isReset) {
            beginDate = beginOfDay((Date)beginDate);
            endDate = beginOfDay((Date)endDate);
        }

        return between((Date)beginDate, (Date)endDate, DateUnit.WEEK);
    }
	// 计算两个日期相差月数在非重置情况下,如果起始日期的天大于结束日期的天,月数要少算1(不足1个月)
    public static long betweenMonth(Date beginDate, Date endDate, boolean isReset) {
        return (new DateBetween(beginDate, endDate)).betweenMonth(isReset);
    }
	// 计算两个日期相差年数在非重置情况下,如果起始日期的月大于结束日期的月,年数要少算1(不足1年)
    public static long betweenYear(Date beginDate, Date endDate, boolean isReset) {
        return (new DateBetween(beginDate, endDate)).betweenYear(isReset);
    }
	// 格式化日期间隔输出
    public static String formatBetween(Date beginDate, Date endDate, Level level) {
        return formatBetween(between(beginDate, endDate, DateUnit.MS), level);
    }
	// 格式化日期间隔输出,精确到毫秒
    public static String formatBetween(Date beginDate, Date endDate) {
        return formatBetween(between(beginDate, endDate, DateUnit.MS));
    }
	// 格式化日期间隔输出
    public static String formatBetween(long betweenMs, Level level) {
        return (new BetweenFormatter(betweenMs, level)).format();
    }
	// 格式化日期间隔输出,精确到毫秒
    public static String formatBetween(long betweenMs) {
        return (new BetweenFormatter(betweenMs, Level.MILLISECOND)).format();
    }
	// 当前日期是否在日期指定范围内 起始日期和结束日期可以互换
    public static boolean isIn(Date date, Date beginDate, Date endDate) {
        return date instanceof DateTime ? ((DateTime)date).isIn(beginDate, endDate) : (new DateTime(date)).isIn(beginDate, endDate);
    }
	// 是否为相同时间 此方法比较两个日期的时间戳是否相同
    public static boolean isSameTime(Date date1, Date date2) {
        return date1.compareTo(date2) == 0;
    }
	// 比较两个日期是否为同一天
    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 != null && date2 != null) {
            return CalendarUtil.isSameDay(calendar(date1), calendar(date2));
        } else {
            throw new IllegalArgumentException("The date must not be null");
        }
    }
	// 比较两个日期是否为同一周
    public static boolean isSameWeek(Date date1, Date date2, boolean isMon) {
        if (date1 != null && date2 != null) {
            return CalendarUtil.isSameWeek(calendar(date1), calendar(date2), isMon);
        } else {
            throw new IllegalArgumentException("The date must not be null");
        }
    }
	// 比较两个日期是否为同一月
    public static boolean isSameMonth(Date date1, Date date2) {
        if (date1 != null && date2 != null) {
            return CalendarUtil.isSameMonth(calendar(date1), calendar(date2));
        } else {
            throw new IllegalArgumentException("The date must not be null");
        }
    }
	// 计时,常用于记录某段代码的执行时间,单位:纳秒
    public static long spendNt(long preTime) {
        return System.nanoTime() - preTime;
    }
	// 计时,常用于记录某段代码的执行时间,单位:毫秒
    public static long spendMs(long preTime) {
        return System.currentTimeMillis() - preTime;
    }
	// 格式化成yyMMddHHmm后转换为int型(过期)
    /** @deprecated */
    @Deprecated
    public static int toIntSecond(Date date) {
        return Integer.parseInt(format(date, "yyMMddHHmm"));
    }
	// 计时器 计算某个过程花费的时间,精确到毫秒
    public static TimeInterval timer() {
        return new TimeInterval();
    }
	// 计时器 计算某个过程花费的时间,精确到毫秒
    public static TimeInterval timer(boolean isNano) {
        return new TimeInterval(isNano);
    }
	// 计时器 创建秒表{@link StopWatch},用于对代码块的执行时间计数
    public static StopWatch createStopWatch() {
        return new StopWatch();
    }
	// 计时器 创建秒表{@link StopWatch},用于对代码块的执行时间计数
    public static StopWatch createStopWatch(String id) {
        return new StopWatch(id);
    }
	// 生日转为年龄,计算法定年龄
    public static int ageOfNow(String birthDay) {
        return ageOfNow((Date)parse(birthDay));
    }
	// 生日转为年龄,计算法定年龄
    public static int ageOfNow(Date birthDay) {
        return age(birthDay, date());
    }
	// 是否闰年
    public static boolean isLeapYear(int year) {
        return Year.isLeap((long)year);
    }
	// 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄
    public static int age(Date birthday, Date dateToCompare) {
        Assert.notNull(birthday, "Birthday can not be null !", new Object[0]);
        if (null == dateToCompare) {
            dateToCompare = date();
        }

        return age(birthday.getTime(), ((Date)dateToCompare).getTime());
    }
	// 是否过期
    /** @deprecated */
    @Deprecated
    public static boolean isExpired(Date startDate, DateField dateField, int timeLength, Date endDate) {
        Date offsetDate = offset(startDate, dateField, timeLength);
        return offsetDate.after(endDate);
    }
	// 是否过期
    /** @deprecated */
    @Deprecated
    public static boolean isExpired(Date startDate, Date endDate, Date checkDate) {
        return betweenMs(startDate, checkDate) > betweenMs(startDate, endDate);
    }
	// HH:mm:ss 时间格式字符串转为秒数
    public static int timeToSecond(String timeStr) {
        if (StrUtil.isEmpty(timeStr)) {
            return 0;
        } else {
            List<String> hms = StrUtil.splitTrim(timeStr, ':', 3);
            int lastIndex = hms.size() - 1;
            int result = 0;

            for(int i = lastIndex; i >= 0; --i) {
                result = (int)((double)result + (double)Integer.parseInt((String)hms.get(i)) * Math.pow(60.0D, (double)(lastIndex - i)));
            }

            return result;
        }
    }
	// 秒数转为时间格式(HH:mm:ss)
    public static String secondToTime(int seconds) {
        if (seconds < 0) {
            throw new IllegalArgumentException("Seconds must be a positive number!");
        } else {
            int hour = seconds / 3600;
            int other = seconds % 3600;
            int minute = other / 60;
            int second = other % 60;
            StringBuilder sb = new StringBuilder();
            if (hour < 10) {
                sb.append("0");
            }

            sb.append(hour);
            sb.append(":");
            if (minute < 10) {
                sb.append("0");
            }

            sb.append(minute);
            sb.append(":");
            if (second < 10) {
                sb.append("0");
            }

            sb.append(second);
            return sb.toString();
        }
    }
	// 创建日期范围生成器
    public static DateRange range(Date start, Date end, DateField unit) {
        return new DateRange(start, end, unit);
    }
	// 创建日期范围内数组
    public static List<DateTime> rangeContains(DateRange start, DateRange end) {
        List<DateTime> startDateTimes = CollUtil.newArrayList(start);
        List<DateTime> endDateTimes = CollUtil.newArrayList(end);
        Stream var10000 = startDateTimes.stream();
        endDateTimes.getClass();
        return (List)var10000.filter(endDateTimes::contains).collect(Collectors.toList());
    }
	// 创建日期范围外数组
    public static List<DateTime> rangeNotContains(DateRange start, DateRange end) {
        List<DateTime> startDateTimes = CollUtil.newArrayList(start);
        List<DateTime> endDateTimes = CollUtil.newArrayList(end);
        return (List)endDateTimes.stream().filter((item) -> {
            return !startDateTimes.contains(item);
        }).collect(Collectors.toList());
    }
	// 创建日期范围自定义返回数组
    public static <T> List<T> rangeFunc(Date start, Date end, DateField unit, Function<Date, T> func) {
        if (start != null && end != null && !start.after(end)) {
            ArrayList<T> list = new ArrayList();
            Iterator var5 = range(start, end, unit).iterator();

            while(var5.hasNext()) {
                DateTime date = (DateTime)var5.next();
                list.add(func.apply(date));
            }

            return list;
        } else {
            return Collections.emptyList();
        }
    }
	// 创建日期范围消费后返回数组
    public static void rangeConsume(Date start, Date end, DateField unit, Consumer<Date> consumer) {
        if (start != null && end != null && !start.after(end)) {
            range(start, end, unit).forEach(consumer);
        }
    }
	// 将时间范围按照总痕步长划分成时间段
    public static List<DateTime> rangeToList(Date start, Date end, DateField unit) {
        return CollUtil.newArrayList(range(start, end, unit));
    }
	// 将时间范围按照总痕步长划分成时间段 (扩大倍数)
    public static List<DateTime> rangeToList(Date start, Date end, DateField unit, int step) {
        return CollUtil.newArrayList(new DateRange(start, end, unit, step));
    }
	// 将时间范围按照总痕步长划分成时间段 (扩大倍数)
    public static String getZodiac(int month, int day) {
        return Zodiac.getZodiac(month, day);
    }
	// 获取中文星座
    public static String getChineseZodiac(int year) {
        return Zodiac.getChineseZodiac(year);
    }
	// 比较大小 (返回数字 0平等 -1 小于 1 大于)
    public static int compare(Date date1, Date date2) {
        return CompareUtil.compare(date1, date2);
    }
	// 日期格式化比较大小 (返回数字 0平等 -1 小于 1 大于)
    public static int compare(Date date1, Date date2, String format) {
        if (format != null) {
            if (date1 != null) {
                date1 = parse((CharSequence)format((Date)date1, (String)format), (String)format);
            }

            if (date2 != null) {
                date2 = parse((CharSequence)format((Date)date2, (String)format), (String)format);
            }
        }

        return CompareUtil.compare((Comparable)date1, (Comparable)date2);
    }
	// 纳秒转毫秒
    public static long nanosToMillis(long duration) {
        return TimeUnit.NANOSECONDS.toMillis(duration);
    }
	// 纳秒转秒
    public static double nanosToSeconds(long duration) {
        return (double)duration / 1.0E9D;
    }
	// Date对象转换为{@link Instant}对象
    public static Instant toInstant(Date date) {
        return null == date ? null : date.toInstant();
    }
	// Date对象转换为{@link Instant}对象
    public static Instant toInstant(TemporalAccessor temporalAccessor) {
        return TemporalAccessorUtil.toInstant(temporalAccessor);
    }
	// {@link Instant} 转换为 {@link LocalDateTime},使用系统默认时区
    public static LocalDateTime toLocalDateTime(Instant instant) {
        return LocalDateTimeUtil.of(instant);
    }
	// {@link Date} 转换为 {@link LocalDateTime},使用系统默认时区
    public static LocalDateTime toLocalDateTime(Date date) {
        return LocalDateTimeUtil.of(date);
    }
	// 转换时区
    public static DateTime convertTimeZone(Date date, ZoneId zoneId) {
        return new DateTime(date, ZoneUtil.toTimeZone(zoneId));
    }
	// 转换时区
    public static DateTime convertTimeZone(Date date, TimeZone timeZone) {
        return new DateTime(date, timeZone);
    }
	// 获取某年多少天
    public static int lengthOfYear(int year) {
        return Year.of(year).length();
    }
	// 获取某月多少天 (是闰年嘛)
    public static int lengthOfMonth(int month, boolean isLeapYear) {
        return java.time.Month.of(month).length(isLeapYear);
    }
	// 时间格式化
    public static SimpleDateFormat newSimpleFormat(String pattern) {
        return newSimpleFormat(pattern, (Locale)null, (TimeZone)null);
    }
	// 时间格式化
    public static SimpleDateFormat newSimpleFormat(String pattern, Locale locale, TimeZone timeZone) {
        if (null == locale) {
            locale = Locale.getDefault(Category.FORMAT);
        }

        SimpleDateFormat format = new SimpleDateFormat(pattern, locale);
        if (null != timeZone) {
            format.setTimeZone(timeZone);
        }

        format.setLenient(false);
        return format;
    }
    // 判断时间类型是什么
    public static String getShotName(TimeUnit unit) {
        switch(unit) {
        case NANOSECONDS:
            return "ns";
        case MICROSECONDS:
            return "μs";
        case MILLISECONDS:
            return "ms";
        case SECONDS:
            return "s";
        case MINUTES:
            return "min";
        case HOURS:
            return "h";
        default:
            return unit.name().toLowerCase();
        }
    }
	// 时间是否重叠
    public static boolean isOverlap(Date realStartTime, Date realEndTime, Date startTime, Date endTime) {
        return realStartTime.compareTo(endTime) <= 0 && startTime.compareTo(realEndTime) <= 0;
    }
	// 当前时间是否是最后一天
    public static boolean isLastDayOfMonth(Date date) {
        return date(date).isLastDayOfMonth();
    }
	// 获取某月最后一天
    public static int getLastDayOfMonth(Date date) {
        return date(date).getLastDayOfMonth();
    }

    private static String normalize(CharSequence dateStr) {
        if (StrUtil.isBlank(dateStr)) {
            return StrUtil.str(dateStr);
        } else {
            List<String> dateAndTime = StrUtil.splitTrim(dateStr, ' ');
            int size = dateAndTime.size();
            if (size >= 1 && size <= 2) {
                StringBuilder builder = StrUtil.builder();
                String datePart = ((String)dateAndTime.get(0)).replaceAll("[/.年月]", "-");
                datePart = StrUtil.removeSuffix(datePart, "日");
                builder.append(datePart);
                if (size == 2) {
                    builder.append(' ');
                    String timePart = ((String)dateAndTime.get(1)).replaceAll("[时分秒]", ":");
                    timePart = StrUtil.removeSuffix(timePart, ":");
                    timePart = timePart.replace(',', '.');
                    builder.append(timePart);
                }

                return builder.toString();
            } else {
                return StrUtil.str(dateStr);
            }
        }
    }
}

日期时间对象

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

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package cn.hutool.core.date;

import cn.hutool.core.date.BetweenFormatter.Level;
import cn.hutool.core.date.format.DateParser;
import cn.hutool.core.date.format.DatePrinter;
import cn.hutool.core.date.format.FastDateFormat;
import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.SystemPropsUtil;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Locale.Category;

public class DateTime extends Date {
    private static final long serialVersionUID = -5395712593979185936L;
    private static boolean useJdkToStringStyle = false;
    private boolean mutable;
    private Week firstDayOfWeek;
    private TimeZone timeZone;
    private int minimalDaysInFirstWeek;
	// 改变useJdkToStringStyle boolean值  为了toString方法是否返回时间格式化数据
    public static void setUseJdkToStringStyle(boolean customUseJdkToStringStyle) {
        useJdkToStringStyle = customUseJdkToStringStyle;
    }
    // 通过毫秒时间戳转换成DateTime类型
    public static DateTime of(long timeMillis) {
        return new DateTime(timeMillis);
    }
    // 通过date转换成DateTime类型
    public static DateTime of(Date date) {
        return date instanceof DateTime ? (DateTime)date : new DateTime(date);
    }
    // 通过日历转换成DateTime类型
    public static DateTime of(Calendar calendar) {
        return new DateTime(calendar);
    }
    // 通过时间字符串和时间格式化类型转换成DateTime类型
    public static DateTime of(String dateStr, String format) {
        return new DateTime(dateStr, format);
    }
    // 获取最新时间
    public static DateTime now() {
        return new DateTime();
    }

    public DateTime() {
        this(TimeZone.getDefault());
    }

    public DateTime(TimeZone timeZone) {
        this(System.currentTimeMillis(), timeZone);
    }

    public DateTime(Date date) {
        this(date, date instanceof DateTime ? ((DateTime)date).timeZone : TimeZone.getDefault());
    }

    public DateTime(Date date, TimeZone timeZone) {
        this(((Date)ObjectUtil.defaultIfNull(date, new Date())).getTime(), timeZone);
    }

    public DateTime(Calendar calendar) {
        this(calendar.getTime(), calendar.getTimeZone());
        this.setFirstDayOfWeek(Week.of(calendar.getFirstDayOfWeek()));
    }

    public DateTime(Instant instant) {
        this(instant.toEpochMilli());
    }

    public DateTime(Instant instant, ZoneId zoneId) {
        this(instant.toEpochMilli(), ZoneUtil.toTimeZone(zoneId));
    }

    public DateTime(TemporalAccessor temporalAccessor) {
        this(TemporalAccessorUtil.toInstant(temporalAccessor));
    }

    public DateTime(ZonedDateTime zonedDateTime) {
        this(zonedDateTime.toInstant(), zonedDateTime.getZone());
    }

    public DateTime(long timeMillis) {
        this(timeMillis, TimeZone.getDefault());
    }

    public DateTime(long timeMillis, TimeZone timeZone) {
        super(timeMillis);
        this.mutable = true;
        this.firstDayOfWeek = Week.MONDAY;
        this.timeZone = (TimeZone)ObjectUtil.defaultIfNull(timeZone, TimeZone::getDefault);
    }

    public DateTime(CharSequence dateStr) {
        this((Date)DateUtil.parse(dateStr));
    }

    public DateTime(CharSequence dateStr, String format) {
        this(GlobalCustomFormat.isCustomFormat(format) ? GlobalCustomFormat.parse(dateStr, format) : parse(dateStr, DateUtil.newSimpleFormat(format)));
    }

    public DateTime(CharSequence dateStr, DateFormat dateFormat) {
        this(parse(dateStr, dateFormat), dateFormat.getTimeZone());
    }

    public DateTime(CharSequence dateStr, DateTimeFormatter formatter) {
        this(TemporalAccessorUtil.toInstant(formatter.parse(dateStr)), formatter.getZone());
    }

    public DateTime(CharSequence dateStr, DateParser dateParser) {
        this(dateStr, dateParser, SystemPropsUtil.getBoolean(SystemPropsUtil.HUTOOL_DATE_LENIENT, true));
    }

    public DateTime(CharSequence dateStr, DateParser dateParser, boolean lenient) {
        this(parse(dateStr, dateParser, lenient));
    }
	// 通过时间单位和偏移量返回新的DateTime 
    public DateTime offset(DateField datePart, int offset) {
        if (DateField.ERA == datePart) {
            throw new IllegalArgumentException("ERA is not support offset!");
        } else {
            Calendar cal = this.toCalendar();
            cal.add(datePart.getValue(), offset);
            DateTime dt = this.mutable ? this : (DateTime)ObjectUtil.clone(this);
            return dt.setTimeInternal(cal.getTimeInMillis());
        }
    }
	// 通过时间单位和偏移量返回新的DateTime
    public DateTime offsetNew(DateField datePart, int offset) {
        Calendar cal = this.toCalendar();
        cal.add(datePart.getValue(), offset);
        return ((DateTime)ObjectUtil.clone(this)).setTimeInternal(cal.getTimeInMillis());
    }

    public int getField(DateField field) {
        return this.getField(field.getValue());
    }

    public int getField(int field) {
        return this.toCalendar().get(field);
    }

    public DateTime setField(DateField field, int value) {
        return this.setField(field.getValue(), value);
    }

    public DateTime setField(int field, int value) {
        Calendar calendar = this.toCalendar();
        calendar.set(field, value);
        DateTime dt = this;
        if (!this.mutable) {
            dt = (DateTime)ObjectUtil.clone(this);
        }

        return dt.setTimeInternal(calendar.getTimeInMillis());
    }

    public void setTime(long time) {
        if (this.mutable) {
            super.setTime(time);
        } else {
            throw new DateException("This is not a mutable object !");
        }
    }
	// 获取年
    public int year() {
        return this.getField(DateField.YEAR);
    }
	// 获取当前第几季度
    public int quarter() {
        return this.month() / 3 + 1;
    }
	// 获取当前第几季度
    public Quarter quarterEnum() {
        return Quarter.of(this.quarter());
    }
	// 获取月
    public int month() {
        return this.getField(DateField.MONTH);
    }
	// 获取月 + 1
    public int monthBaseOne() {
        return this.month() + 1;
    }
	// 获取月 + 1
    public int monthStartFromOne() {
        return this.month() + 1;
    }

    public Month monthEnum() {
        return Month.of(this.month());
    }
	// 获取一年中的一周
    public int weekOfYear() {
        return this.getField(DateField.WEEK_OF_YEAR);
    }
	// 获取一月中的一周
    public int weekOfMonth() {
        return this.getField(DateField.WEEK_OF_MONTH);
    }
	// 获取一月中的一天
    public int dayOfMonth() {
        return this.getField(DateField.DAY_OF_MONTH);
    }
	// 获取一年中的一天
    public int dayOfYear() {
        return this.getField(DateField.DAY_OF_YEAR);
    }
	// 获取一周中的一天
    public int dayOfWeek() {
        return this.getField(DateField.DAY_OF_WEEK);
    }
	// 获取一月中一周中的一天
    public int dayOfWeekInMonth() {
        return this.getField(DateField.DAY_OF_WEEK_IN_MONTH);
    }
	// 获取一周中的一天
    public Week dayOfWeekEnum() {
        return Week.of(this.dayOfWeek());
    }
	// 获取当时小时(是否24小时)
    public int hour(boolean is24HourClock) {
        return this.getField(is24HourClock ? DateField.HOUR_OF_DAY : DateField.HOUR);
    }	
	// 获取当时分钟
    public int minute() {
        return this.getField(DateField.MINUTE);
    }
	// 获取当时秒
    public int second() {
        return this.getField(DateField.SECOND);
    }
	// 获取当时毫秒
    public int millisecond() {
        return this.getField(DateField.MILLISECOND);
    }
	// 是否上午
    public boolean isAM() {
        return 0 == this.getField(DateField.AM_PM);
    }
	// 是否下午
    public boolean isPM() {
        return 1 == this.getField(DateField.AM_PM);
    }
	// 是否周末
    public boolean isWeekend() {
        int dayOfWeek = this.dayOfWeek();
        return 7 == dayOfWeek || 1 == dayOfWeek;
    }
	// 是否闰年
    public boolean isLeapYear() {
        return DateUtil.isLeapYear(this.year());
    }
	// 当前时间转成日历 指定格式化
    public Calendar toCalendar() {
        return this.toCalendar(Locale.getDefault(Category.FORMAT));
    }
	// 当前时间转成日历 自定义格式化
    public Calendar toCalendar(Locale locale) {
        return this.toCalendar(this.timeZone, locale);
    }
	// 当前时间转成日历 自定义时区
    public Calendar toCalendar(TimeZone zone) {
        return this.toCalendar(zone, Locale.getDefault(Category.FORMAT));
    }
	// 当前时间转成日历 自定义时区 自定义格式化
    public Calendar toCalendar(TimeZone zone, Locale locale) {
        if (null == locale) {
            locale = Locale.getDefault(Category.FORMAT);
        }

        Calendar cal = null != zone ? Calendar.getInstance(zone, locale) : Calendar.getInstance(locale);
        cal.setFirstDayOfWeek(this.firstDayOfWeek.getValue());
        if (this.minimalDaysInFirstWeek > 0) {
            cal.setMinimalDaysInFirstWeek(this.minimalDaysInFirstWeek);
        }

        cal.setTime(this);
        return cal;
    }
	// 当前时间转成Jdk date
    public Date toJdkDate() {
        return new Date(this.getTime());
    }
	// 当前时间转成时间戳
    public Timestamp toTimestamp() {
        return new Timestamp(this.getTime());
    }
	// 当前时间转成Sql date
    public java.sql.Date toSqlDate() {
        return new java.sql.Date(this.getTime());
    }
	// 当前时间转成LocalDateTime
    public LocalDateTime toLocalDateTime() {
        return LocalDateTimeUtil.of(this);
    }
	// 当前时间和指定时间进行对比得到的Date对象
    public DateBetween between(Date date) {
        return new DateBetween(this, date);
    }
	// 通过时间单位把当前时间和指定时间进行对比得出数值
    public long between(Date date, DateUnit unit) {
        return (new DateBetween(this, date)).between(unit);
    }
	// 通过时间单位和 时间等级把当前时间和指定时间进行对比得出几天或者几秒 字符串
    public String between(Date date, DateUnit unit, Level formatLevel) {
        return (new DateBetween(this, date)).toString(unit, formatLevel);
    }
	// 判断当前是否在规定的范围内
    public boolean isIn(Date beginDate, Date endDate) {
        long beginMills = beginDate.getTime();
        long endMills = endDate.getTime();
        long thisMills = this.getTime();
        return thisMills >= Math.min(beginMills, endMills) && thisMills <= Math.max(beginMills, endMills);
    }
	// 判断当前时间是否指定时间之前
    public boolean isBefore(Date date) {
        if (null == date) {
            throw new NullPointerException("Date to compare is null !");
        } else {
            return this.compareTo(date) < 0;
        }
    }
	// 判断当前时间是否指定时间之前或者相等
    public boolean isBeforeOrEquals(Date date) {
        if (null == date) {
            throw new NullPointerException("Date to compare is null !");
        } else {
            return this.compareTo(date) <= 0;
        }
    }
	// 判断当前时间是否指定时间之后
    public boolean isAfter(Date date) {
        if (null == date) {
            throw new NullPointerException("Date to compare is null !");
        } else {
            return this.compareTo(date) > 0;
        }
    }
	// 判断当前时间是否指定时间之后或者相等
    public boolean isAfterOrEquals(Date date) {
        if (null == date) {
            throw new NullPointerException("Date to compare is null !");
        } else {
            return this.compareTo(date) >= 0;
        }
    }

    public boolean isMutable() {
        return this.mutable;
    }

    public DateTime setMutable(boolean mutable) {
        this.mutable = mutable;
        return this;
    }
	// 得到一周的第一天
    public Week getFirstDayOfWeek() {
        return this.firstDayOfWeek;
    }
	// 设置一周的第一天
    public DateTime setFirstDayOfWeek(Week firstDayOfWeek) {
        this.firstDayOfWeek = firstDayOfWeek;
        return this;
    }
   // 
    public TimeZone getTimeZone() {
        return this.timeZone;
    }

    public ZoneId getZoneId() {
        return this.timeZone.toZoneId();
    }

    public DateTime setTimeZone(TimeZone timeZone) {
        this.timeZone = (TimeZone)ObjectUtil.defaultIfNull(timeZone, TimeZone::getDefault);
        return this;
    }
    // 设置第一周最少天数
    public DateTime setMinimalDaysInFirstWeek(int minimalDaysInFirstWeek) {
        this.minimalDaysInFirstWeek = minimalDaysInFirstWeek;
        return this;
    }
    // 是否是一月最后一天
    public boolean isLastDayOfMonth() {
        return this.dayOfMonth() == this.getLastDayOfMonth();
    }
    // 获取这个月最后一天
    public int getLastDayOfMonth() {
        return this.monthEnum().getLastDay(this.isLeapYear());
    }

    public String toString() {
        return useJdkToStringStyle ? super.toString() : this.toString(this.timeZone);
    }

    public String toStringDefaultTimeZone() {
        return this.toString(TimeZone.getDefault());
    }

    public String toString(TimeZone timeZone) {
        return null != timeZone ? this.toString((DateFormat)DateUtil.newSimpleFormat("yyyy-MM-dd HH:mm:ss", (Locale)null, timeZone)) : this.toString((DatePrinter)DatePattern.NORM_DATETIME_FORMAT);
    }

    public String toDateStr() {
        return null != this.timeZone ? this.toString((DateFormat)DateUtil.newSimpleFormat("yyyy-MM-dd", (Locale)null, this.timeZone)) : this.toString((DatePrinter)DatePattern.NORM_DATE_FORMAT);
    }

    public String toTimeStr() {
        return null != this.timeZone ? this.toString((DateFormat)DateUtil.newSimpleFormat("HH:mm:ss", (Locale)null, this.timeZone)) : this.toString((DatePrinter)DatePattern.NORM_TIME_FORMAT);
    }

    public String toString(String format) {
        return null != this.timeZone ? this.toString((DateFormat)DateUtil.newSimpleFormat(format, (Locale)null, this.timeZone)) : this.toString((DatePrinter)FastDateFormat.getInstance(format));
    }

    public String toString(DatePrinter format) {
        return format.format(this);
    }

    public String toString(DateFormat format) {
        return format.format(this);
    }

    public String toMsStr() {
        return this.toString((DatePrinter)DatePattern.NORM_DATETIME_MS_FORMAT);
    }

    private static Date parse(CharSequence dateStr, DateFormat dateFormat) {
        Assert.notBlank(dateStr, "Date String must be not blank !", new Object[0]);

        try {
            return dateFormat.parse(dateStr.toString());
        } catch (Exception var4) {
            String pattern;
            if (dateFormat instanceof SimpleDateFormat) {
                pattern = ((SimpleDateFormat)dateFormat).toPattern();
            } else {
                pattern = dateFormat.toString();
            }

            throw new DateException(StrUtil.format("Parse [{}] with format [{}] error!", new Object[]{dateStr, pattern}), var4);
        }
    }

    private static Calendar parse(CharSequence dateStr, DateParser parser, boolean lenient) {
        Assert.notNull(parser, "Parser or DateFromat must be not null !", new Object[0]);
        Assert.notBlank(dateStr, "Date String must be not blank !", new Object[0]);
        Calendar calendar = CalendarUtil.parse(dateStr, lenient, parser);
        if (null == calendar) {
            throw new DateException("Parse [{}] with format [{}] error!", new Object[]{dateStr, parser.getPattern()});
        } else {
            calendar.setFirstDayOfWeek(Week.MONDAY.getValue());
            return calendar;
        }
    }

    private DateTime setTimeInternal(long time) {
        super.setTime(time);
        return this;
    }
}

农历日期

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

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package cn.hutool.core.date;

import cn.hutool.core.convert.NumberChineseFormatter;
import cn.hutool.core.date.chinese.ChineseMonth;
import cn.hutool.core.date.chinese.GanZhi;
import cn.hutool.core.date.chinese.LunarFestival;
import cn.hutool.core.date.chinese.LunarInfo;
import cn.hutool.core.date.chinese.SolarTerms;
import cn.hutool.core.util.StrUtil;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;

public class ChineseDate {
    private final int year;
    private final int month;
    private final boolean isLeapMonth;
    private final int day;
    private final int gyear;
    private final int gmonthBase1;
    private final int gday;
	//通过公历构建
    public ChineseDate(Date date) {
        this(LocalDateTimeUtil.ofDate(date.toInstant()));
    }
	//通过公历构建
    public ChineseDate(LocalDate localDate) {
        this.gyear = localDate.getYear();
        this.gmonthBase1 = localDate.getMonthValue();
        this.gday = localDate.getDayOfMonth();
        int offset = (int)(localDate.toEpochDay() - LunarInfo.BASE_DAY);

        int iYear;
        for(iYear = 1900; iYear <= LunarInfo.MAX_YEAR; ++iYear) {
            int daysOfYear = LunarInfo.yearDays(iYear);
            if (offset < daysOfYear) {
                break;
            }

            offset -= daysOfYear;
        }

        this.year = iYear;
        int leapMonth = LunarInfo.leapMonth(iYear);
        boolean hasLeapMonth = false;

        int month;
        for(month = 1; month < 13; ++month) {
            int daysOfMonth;
            if (leapMonth > 0 && month == leapMonth + 1) {
                daysOfMonth = LunarInfo.leapDays(this.year);
                hasLeapMonth = true;
            } else {
                daysOfMonth = LunarInfo.monthDays(this.year, hasLeapMonth ? month - 1 : month);
            }

            if (offset < daysOfMonth) {
                break;
            }

            offset -= daysOfMonth;
        }

        this.isLeapMonth = leapMonth > 0 && month == leapMonth + 1;
        if (hasLeapMonth && !this.isLeapMonth) {
            --month;
        }

        this.month = month;
        this.day = offset + 1;
    }
	//通过农历构建
    public ChineseDate(int chineseYear, int chineseMonth, int chineseDay) {
        this(chineseYear, chineseMonth, chineseDay, chineseMonth == LunarInfo.leapMonth(chineseYear));
    }
	//通过农历构建
    public ChineseDate(int chineseYear, int chineseMonth, int chineseDay, boolean isLeapMonth) {
        if (chineseMonth != LunarInfo.leapMonth(chineseYear)) {
            isLeapMonth = false;
        }

        this.day = chineseDay;
        this.isLeapMonth = isLeapMonth;
        this.month = isLeapMonth ? chineseMonth + 1 : chineseMonth;
        this.year = chineseYear;
        DateTime dateTime = this.lunar2solar(chineseYear, chineseMonth, chineseDay, isLeapMonth);
        if (null != dateTime) {
            this.gday = dateTime.dayOfMonth();
            this.gmonthBase1 = dateTime.month() + 1;
            this.gyear = dateTime.year();
        } else {
            this.gday = -1;
            this.gmonthBase1 = -1;
            this.gyear = -1;
        }

    }
	// 得到中国年
    public int getChineseYear() {
        return this.year;
    }
	// 得到阳历年
    public int getGregorianYear() {
        return this.gyear;
    }
	// 得到月份
    public int getMonth() {
        return this.month;
    }
	// 获取阳历月Base1
    public int getGregorianMonthBase1() {
        return this.gmonthBase1;
    }
	// 获取阳历月
    public int getGregorianMonth() {
        return this.gmonthBase1 - 1;
    }
	// 获取阳历月
    public boolean isLeapMonth() {
        return this.isLeapMonth;
    }
	// 获取中国月份
    public String getChineseMonth() {
        return this.getChineseMonth(false);
    }
	// 获取中国月份姓名
    public String getChineseMonthName() {
        return this.getChineseMonth(true);
    }
	// 获得农历月份(中文,例如二月,十二月,或者润一月)
    public String getChineseMonth(boolean isTraditional) {
        return ChineseMonth.getChineseMonthName(this.isLeapMonth(), this.isLeapMonth() ? this.month - 1 : this.month, isTraditional);
    }
	// 获取农历的日,从1开始计数
    public int getDay() {
        return this.day;
    }
	// 获取公历的日
    public int getGregorianDay() {
        return this.gday;
    }
	// 获得农历日
    public String getChineseDay() {
        String[] chineseTen = new String[]{"初", "十", "廿", "卅"};
        int n = this.day % 10 == 0 ? 9 : this.day % 10 - 1;
        if (this.day > 30) {
            return "";
        } else {
            switch(this.day) {
            case 10:
                return "初十";
            case 20:
                return "二十";
            case 30:
                return "三十";
            default:
                return chineseTen[this.day / 10] + NumberChineseFormatter.format((long)(n + 1), false);
            }
        }
    }
	// 获取农历Date
    public Date getGregorianDate() {
        return DateUtil.date(this.getGregorianCalendar());
    }
	// 获取农历Calendar
    public Calendar getGregorianCalendar() {
        Calendar calendar = CalendarUtil.calendar();
        calendar.set(this.gyear, this.getGregorianMonth(), this.gday, 0, 0, 0);
        return calendar;
    }
	// 获得节日,闰月不计入节日中
    public String getFestivals() {
        return StrUtil.join(",", LunarFestival.getFestivals(this.year, this.month, this.day));
    }
	// 获得节日,闰月不计入节日中
    public String getChineseZodiac() {
        return Zodiac.getChineseZodiac(this.year);
    }
	// 获得年的天干地支
    public String getCyclical() {
        return GanZhi.getGanzhiOfYear(this.year);
    }
	// 获得年的天干地支信息
    public String getCyclicalYMD() {
        return this.gyear >= 1900 && this.gmonthBase1 > 0 && this.gday > 0 ? this.cyclicalm(this.gyear, this.gmonthBase1, this.gday) : null;
    }
	// 获得节气
    public String getTerm() {
        return SolarTerms.getTerm(this.gyear, this.gmonthBase1, this.gday);
    }
	// 转换为标准的日期格式来表示农历日期,例如2020-01-13如果存在闰月,显示闰月月份,如润二月显示2
    public String toStringNormal() {
        return String.format("%04d-%02d-%02d", this.year, this.isLeapMonth() ? this.month - 1 : this.month, this.day);
    }
	// 农历年 生肖年 农历月份名字 农历日
    public String toString() {
        return String.format("%s%s年 %s%s", this.getCyclical(), this.getChineseZodiac(), this.getChineseMonthName(), this.getChineseDay());
    }
	// 传入 月日的offset 传回干支, 0=甲子
    private String cyclicalm(int year, int month, int day) {
        return StrUtil.format("{}年{}月{}日", new Object[]{GanZhi.getGanzhiOfYear(this.year), GanZhi.getGanzhiOfMonth(year, month, day), GanZhi.getGanzhiOfDay(year, month, day)});
    }

    private DateTime lunar2solar(int chineseYear, int chineseMonth, int chineseDay, boolean isLeapMonth) {
        if (chineseYear == 2100 && chineseMonth == 12 && chineseDay > 1 || chineseYear == 1900 && chineseMonth == 1 && chineseDay < 31) {
            return null;
        } else {
            int day = LunarInfo.monthDays(chineseYear, chineseMonth);
            int _day = day;
            if (isLeapMonth) {
                _day = LunarInfo.leapDays(chineseYear);
            }

            if (chineseYear >= 1900 && chineseYear <= 2100 && chineseDay <= _day) {
                int offset = 0;

                int leap;
                for(leap = 1900; leap < chineseYear; ++leap) {
                    offset += LunarInfo.yearDays(leap);
                }

                boolean isAdd = false;

                for(int i = 1; i < chineseMonth; ++i) {
                    leap = LunarInfo.leapMonth(chineseYear);
                    if (!isAdd && leap <= i && leap > 0) {
                        offset += LunarInfo.leapDays(chineseYear);
                        isAdd = true;
                    }

                    offset += LunarInfo.monthDays(chineseYear, i);
                }

                if (isLeapMonth) {
                    offset += day;
                }

                return DateUtil.date((long)(offset + chineseDay - 31) * 86400000L - 2203804800000L);
            } else {
                return null;
            }
        }
    }
}

LocalDateTime工具

从Hutool的5.4.x开始,Hutool加入了针对JDK8+日期API的封装,此工具类的功能包括LocalDateTime和LocalDate的解析、格式化、转换等操作。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package cn.hutool.core.date;

import cn.hutool.core.date.format.GlobalCustomFormat;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.chrono.ChronoLocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalUnit;
import java.time.temporal.WeekFields;
import java.util.Date;
import java.util.TimeZone;

public class LocalDateTimeUtil {
    public LocalDateTimeUtil() {
    }
	// 返回现在时间的 LocalDateTime
    public static LocalDateTime now() {
        return LocalDateTime.now();
    }
	//Date对象转换为LocalDateTime
    public static LocalDateTime of(Instant instant) {
        return of(instant, ZoneId.systemDefault());
    }
	// 时间戳转换为LocalDateTime
    public static LocalDateTime ofUTC(Instant instant) {
        return of(instant, ZoneId.of("UTC"));
    }
	// zonedDateTime转LocalDateTime
    public static LocalDateTime of(ZonedDateTime zonedDateTime) {
        return null == zonedDateTime ? null : zonedDateTime.toLocalDateTime();
    }
	// Instant转LocalDateTime
    public static LocalDateTime of(Instant instant, ZoneId zoneId) {
        return null == instant ? null : LocalDateTime.ofInstant(instant, (ZoneId)ObjectUtil.defaultIfNull(zoneId, ZoneId::systemDefault));
    }
	
    public static LocalDateTime of(Instant instant, TimeZone timeZone) {
        return null == instant ? null : of(instant, ((TimeZone)ObjectUtil.defaultIfNull(timeZone, TimeZone::getDefault)).toZoneId());
    }
	// 毫秒转LocalDateTime,使用默认时区
    public static LocalDateTime of(long epochMilli) {
        return of(Instant.ofEpochMilli(epochMilli));
    }
	// 毫秒转LocalDateTime,使用UTC时区
    public static LocalDateTime ofUTC(long epochMilli) {
        return ofUTC(Instant.ofEpochMilli(epochMilli));
    }
	// 毫秒转LocalDateTime,根据时区不同,结果会产生时间偏移
    public static LocalDateTime of(long epochMilli, ZoneId zoneId) {
        return of(Instant.ofEpochMilli(epochMilli), zoneId);
    }
	// 毫秒转LocalDateTime,结果会产生时间偏移
    public static LocalDateTime of(long epochMilli, TimeZone timeZone) {
        return of(Instant.ofEpochMilli(epochMilli), timeZone);
    }
	// Date转LocalDateTime,使用默认时区
    public static LocalDateTime of(Date date) {
        if (null == date) {
            return null;
        } else {
            return date instanceof DateTime ? of(date.toInstant(), ((DateTime)date).getZoneId()) : of(date.toInstant());
        }
    }
	// TemporalAccessor转LocalDate,使用默认时区
    public static LocalDateTime of(TemporalAccessor temporalAccessor) {
        if (null == temporalAccessor) {
            return null;
        } else if (temporalAccessor instanceof LocalDate) {
            return ((LocalDate)temporalAccessor).atStartOfDay();
        } else if (temporalAccessor instanceof Instant) {
            return LocalDateTime.ofInstant((Instant)temporalAccessor, ZoneId.systemDefault());
        } else {
            return temporalAccessor instanceof ZonedDateTime ? ((ZonedDateTime)temporalAccessor).toLocalDateTime() : LocalDateTime.of(TemporalAccessorUtil.get(temporalAccessor, ChronoField.YEAR), TemporalAccessorUtil.get(temporalAccessor, ChronoField.MONTH_OF_YEAR), TemporalAccessorUtil.get(temporalAccessor, ChronoField.DAY_OF_MONTH), TemporalAccessorUtil.get(temporalAccessor, ChronoField.HOUR_OF_DAY), TemporalAccessorUtil.get(temporalAccessor, ChronoField.MINUTE_OF_HOUR), TemporalAccessorUtil.get(temporalAccessor, ChronoField.SECOND_OF_MINUTE), TemporalAccessorUtil.get(temporalAccessor, ChronoField.NANO_OF_SECOND));
        }
    }
	// TemporalAccessor转LocalDate,使用默认时区
    public static LocalDate ofDate(TemporalAccessor temporalAccessor) {
        if (null == temporalAccessor) {
            return null;
        } else if (temporalAccessor instanceof LocalDateTime) {
            return ((LocalDateTime)temporalAccessor).toLocalDate();
        } else {
            return temporalAccessor instanceof Instant ? of(temporalAccessor).toLocalDate() : LocalDate.of(TemporalAccessorUtil.get(temporalAccessor, ChronoField.YEAR), TemporalAccessorUtil.get(temporalAccessor, ChronoField.MONTH_OF_YEAR), TemporalAccessorUtil.get(temporalAccessor, ChronoField.DAY_OF_MONTH));
        }
    }
	// 解析日期时间字符串为LocalDateTime,仅支持yyyy-MM-dd'T'HH:mm:ss格式,例如:2007-12-03T10:15:30
    public static LocalDateTime parse(CharSequence text) {
        return parse(text, (DateTimeFormatter)null);
    }
	// 解析日期时间字符串为LocalDateTime,格式支持日期时间、日期、时间
    public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) {
        if (StrUtil.isBlank(text)) {
            return null;
        } else {
            return null == formatter ? LocalDateTime.parse(text) : of(formatter.parse(text));
        }
    }
	// 解析日期时间字符串为LocalDateTime
    public static LocalDateTime parse(CharSequence text, String format) {
        if (StrUtil.isBlank((CharSequence)text)) {
            return null;
        } else if (GlobalCustom
        Format.isCustomFormat(format)) {
            return of(GlobalCustomFormat.parse((CharSequence)text, format));
        } else {
            DateTimeFormatter formatter = null;
            if (StrUtil.isNotBlank(format)) {
                if (StrUtil.startWithIgnoreEquals(format, "yyyyMMddHHmmss")) {
                    String fraction = StrUtil.removePrefix(format, "yyyyMMddHHmmss");
                    if (ReUtil.isMatch("[S]{1,2}", fraction)) {
                        text = text + StrUtil.repeat('0', 3 - fraction.length());
                    }

                    formatter = (new DateTimeFormatterBuilder()).appendPattern("yyyyMMddHHmmss").appendValue(ChronoField.MILLI_OF_SECOND, 3).toFormatter();
                } else {
                    formatter = DateTimeFormatter.ofPattern(format);
                }
            }

            return parse((CharSequence)text, (DateTimeFormatter)formatter);
        }
    }
	// 解析日期时间字符串为LocalDate,仅支持yyyy-MM-dd'T'HH:mm:ss格式,例如:2007-12-03T10:15:30
    public static LocalDate parseDate(CharSequence text) {
        return parseDate(text, (DateTimeFormatter)null);
    }
	// 解析日期时间字符串为LocalDate,格式支持日期
    public static LocalDate parseDate(CharSequence text, DateTimeFormatter formatter) {
        if (null == text) {
            return null;
        } else {
            return null == formatter ? LocalDate.parse(text) : ofDate(formatter.parse(text));
        }
    }
	// 解析日期字符串为LocalDate
    public static LocalDate parseDate(CharSequence text, String format) {
        return null == text ? null : parseDate(text, DateTimeFormatter.ofPattern(format));
    }
	// 格式化日期时间为yyyy-MM-dd HH:mm:ss格式
    public static String formatNormal(LocalDateTime time) {
        return format(time, DatePattern.NORM_DATETIME_FORMATTER);
    }
	// 格式化日期时间为指定格式
    public static String format(LocalDateTime time, DateTimeFormatter formatter) {
        return TemporalAccessorUtil.format(time, formatter);
    }
	// 格式化日期时间为指定格式
    public static String format(LocalDateTime time, String format) {
        return TemporalAccessorUtil.format(time, format);
    }
	// 格式化日期时间为yyyy-MM-dd格式
    public static String formatNormal(LocalDate date) {
        return format(date, DatePattern.NORM_DATE_FORMATTER);
    }
	//格式化日期时间为指定格式
    public static String format(LocalDate date, DateTimeFormatter formatter) {
        return TemporalAccessorUtil.format(date, formatter);
    }
	// 格式化日期时间为指定格式
    public static String format(LocalDate date, String format) {
        return null == date ? null : format(date, DateTimeFormatter.ofPattern(format));
    }
	// 日期偏移,根据field不同加不同值(偏移会修改传入的对象)
    public static LocalDateTime offset(LocalDateTime time, long number, TemporalUnit field) {
        return (LocalDateTime)TemporalUtil.offset(time, number, field);
    }
	// 获取两个日期的差,如果结束时间早于开始时间,获取结果为负。返回结果为Duration对象,通过调用toXXX方法返回相差单位
    public static Duration between(LocalDateTime startTimeInclude, LocalDateTime endTimeExclude) {
        return TemporalUtil.between(startTimeInclude, endTimeExclude);
    }
	// 获取两个日期的差,如果结束时间早于开始时间,获取结果为负。返回结果为时间差的long值
    public static long between(LocalDateTime startTimeInclude, LocalDateTime endTimeExclude, ChronoUnit unit) {
        return TemporalUtil.between(startTimeInclude, endTimeExclude, unit);
    }
	// 获取两个日期的表象时间差,如果结束时间早于开始时间,获取结果为负。比如2011年2月1日,和2021年8月11日,日相差了10天,月相差6月
    public static Period betweenPeriod(LocalDate startTimeInclude, LocalDate endTimeExclude) {
        return Period.between(startTimeInclude, endTimeExclude);
    }
	// 修改为一天的开始时间,例如:2020-02-02 00:00:00,000
    public static LocalDateTime beginOfDay(LocalDateTime time) {
        return time.with(LocalTime.MIN);
    }
	// 修改为一天的结束时间,例如:2020-02-02 23:59:59,999
    public static LocalDateTime endOfDay(LocalDateTime time) {
        return endOfDay(time, false);
    }
	// 修改为一天的结束时间,例如:毫秒不归零:2020-02-02 23:59:59,999毫秒归零:2020-02-02 23:59:59,000
    public static LocalDateTime endOfDay(LocalDateTime time, boolean truncateMillisecond) {
        return truncateMillisecond ? time.with(LocalTime.of(23, 59, 59)) : time.with(LocalTime.MAX);
    }
	// TemporalAccessor转换为 时间戳(从1970-01-01T00:00:00Z开始的毫秒数)
    public static long toEpochMilli(TemporalAccessor temporalAccessor) {
        return TemporalAccessorUtil.toEpochMilli(temporalAccessor);
    }
	// 是否为周末(周六或周日)
    public static boolean isWeekend(LocalDateTime localDateTime) {
        return isWeekend(localDateTime.toLocalDate());
    }
	// 是否为周末(周六或周日)
    public static boolean isWeekend(LocalDate localDate) {
        DayOfWeek dayOfWeek = localDate.getDayOfWeek();
        return DayOfWeek.SATURDAY == dayOfWeek || DayOfWeek.SUNDAY == dayOfWeek;
    }
	// 获取LocalDate对应的星期值
    public static Week dayOfWeek(LocalDate localDate) {
        return Week.of(localDate.getDayOfWeek());
    }
	// 检查两个时间段是否有时间重叠
    public static boolean isOverlap(ChronoLocalDateTime<?> realStartTime, ChronoLocalDateTime<?> realEndTime, ChronoLocalDateTime<?> startTime, ChronoLocalDateTime<?> endTime) {
        return realStartTime.compareTo(endTime) <= 0 && startTime.compareTo(realEndTime) <= 0;
    }
		// 获得指定日期是所在年份的第几周
    public static int weekOfYear(TemporalAccessor date) {
        return TemporalAccessorUtil.get(date, WeekFields.ISO.weekOfYear());
    }
	// 比较两个日期是否为同一天
    public static boolean isSameDay(LocalDateTime date1, LocalDateTime date2) {
        return date1 != null && date2 != null && isSameDay(date1.toLocalDate(), date2.toLocalDate());
    }
	// 比较两个日期是否为同一天
    public static boolean isSameDay(LocalDate date1, LocalDate date2) {
        return date1 != null && date2 != null && date1.isEqual(date2);
    }
	// 当前日期是否在日期指定范围内 起始日期和结束日期可以互换
    public static boolean isIn(ChronoLocalDateTime<?> date, ChronoLocalDateTime<?> beginDate, ChronoLocalDateTime<?> endDate) {
        return TemporalAccessorUtil.isIn(date, beginDate, endDate);
    }
	// 判断当前时间(默认时区)是否在指定范围内 起始时间和结束时间可以互换
    public static boolean isIn(ChronoLocalDateTime<?> date, ChronoLocalDateTime<?> beginDate, ChronoLocalDateTime<?> endDate, boolean includeBegin, boolean includeEnd) {
        return TemporalAccessorUtil.isIn(date, beginDate, endDate, includeBegin, includeEnd);
    }
}

计时器工具

Hutool通过封装TimeInterval实现计时器功能,即可以计算方法或过程执行的时间。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package cn.hutool.core.date;

public class TimeInterval extends GroupTimeInterval {
    private static final long serialVersionUID = 1L;
    private static final String DEFAULT_ID = "";

    public TimeInterval() {
        this(false);
    }

    public TimeInterval(boolean isNano) {
        super(isNano);
        this.start();
    }
	// 开始计时并返回当前时间
    public long start() {
        return this.start("");
    }
	// 重新计时并返回从开始到当前的持续时间
    public long intervalRestart() {
        return this.intervalRestart("");
    }
	// 重新开始计算时间(重置开始时间)
    public TimeInterval restart() {
        this.start("");
        return this;
    }
	// 从开始到当前的间隔时间(毫秒数)如果使用纳秒计时,返回纳秒差,否则返回毫秒差
    public long interval() {
        return this.interval("");
    }
	// 从开始到当前的间隔时间(毫秒数),返回XX天XX小时XX分XX秒XX毫秒
    public String intervalPretty() {
        return this.intervalPretty("");
    }
	// 从开始到当前的间隔时间(毫秒数)
    public long intervalMs() {
        return this.intervalMs("");
    }
	// 从开始到当前的间隔秒数,取绝对值
    public long intervalSecond() {
        return this.intervalSecond("");
    }
	// 从开始到当前的间隔分钟数,取绝对值
    public long intervalMinute() {
        return this.intervalMinute("");
    }
	// 从开始到当前的间隔小时数,取绝对值
    public long intervalHour() {
        return this.intervalHour("");
    }
	// 从开始到当前的间隔天数,取绝对值
    public long intervalDay() {
        return this.intervalDay("");
    }
	// 从开始到当前的间隔周数,取绝对值
    public long intervalWeek() {
        return this.intervalWeek("");
    }
}

IO流相关

IO工具类的存在主要针对InputStream、OutputStream、Reader、Writer封装简化,并对NIO相关操作做封装简化

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package cn.hutool.core.io;

import cn.hutool.core.collection.LineIter;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.copy.ReaderWriterCopier;
import cn.hutool.core.io.copy.StreamCopier;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.Flushable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PushbackInputStream;
import java.io.PushbackReader;
import java.io.Reader;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Iterator;
import java.util.Objects;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.Checksum;

public class IoUtil extends NioUtil {
    public IoUtil() {
    }
	// 将Reader中的内容复制到Writer中 使用默认缓存大小,拷贝后不关闭Reader
    public static long copy(Reader reader, Writer writer) throws IORuntimeException {
        return copy((Reader)reader, (Writer)writer, 8192);
    }
	//将Reader中的内容复制到Writer中,拷贝后不关闭Reader
    public static long copy(Reader reader, Writer writer, int bufferSize) throws IORuntimeException {
        return copy((Reader)reader, (Writer)writer, bufferSize, (StreamProgress)null);
    }
	// 将Reader中的内容复制到Writer中,拷贝后不关闭Reader
    public static long copy(Reader reader, Writer writer, int bufferSize, StreamProgress streamProgress) throws IORuntimeException {
        return copy(reader, writer, bufferSize, -1L, streamProgress);
    }
	// 将Reader中的内容复制到Writer中,拷贝后不关闭Reader
    public static long copy(Reader reader, Writer writer, int bufferSize, long count, StreamProgress streamProgress) throws IORuntimeException {
        return (new ReaderWriterCopier(bufferSize, count, streamProgress)).copy(reader, writer);
    }
	// 拷贝流,使用默认Buffer大小,拷贝后不关闭流
    public static long copy(InputStream in, OutputStream out) throws IORuntimeException {
        return copy((InputStream)in, (OutputStream)out, 8192);
    }
	// 拷贝流,拷贝后不关闭流
    public static long copy(InputStream in, OutputStream out, int bufferSize) throws IORuntimeException {
        return copy((InputStream)in, (OutputStream)out, bufferSize, (StreamProgress)null);
    }
	// 拷贝流,拷贝后不关闭流
    public static long copy(InputStream in, OutputStream out, int bufferSize, StreamProgress streamProgress) throws IORuntimeException {
        return copy(in, out, bufferSize, -1L, streamProgress);
    }
	// 拷贝流,拷贝后不关闭流
    public static long copy(InputStream in, OutputStream out, int bufferSize, long count, StreamProgress streamProgress) throws IORuntimeException {
        return (new StreamCopier(bufferSize, count, streamProgress)).copy(in, out);
    }
	// 拷贝文件流,使用NIO
    public static long copy(FileInputStream in, FileOutputStream out) throws IORuntimeException {
        Assert.notNull(in, "FileInputStream is null!", new Object[0]);
        Assert.notNull(out, "FileOutputStream is null!", new Object[0]);
        FileChannel inChannel = null;
        FileChannel outChannel = null;

        long var4;
        try {
            inChannel = in.getChannel();
            outChannel = out.getChannel();
            var4 = copy((FileChannel)inChannel, (FileChannel)outChannel);
        } finally {
            close(outChannel);
            close(inChannel);
        }

        return var4;
    }
	// 获得一个文件读取器,默认使用UTF-8编码
    public static BufferedReader getUtf8Reader(InputStream in) {
        return getReader(in, CharsetUtil.CHARSET_UTF_8);
    }

    /** @deprecated */
    @Deprecated
    public static BufferedReader getReader(InputStream in, String charsetName) {
        return getReader(in, Charset.forName(charsetName));
    }
	// 从BOMInputStream中获取Reader
    public static BufferedReader getReader(BOMInputStream in) {
        return getReader(in, (String)in.getCharset());
    }
	// 从InputStream中获取BomReader
    public static BomReader getBomReader(InputStream in) {
        return new BomReader(in);
    }
	// 获得一个Reader
    public static BufferedReader getReader(InputStream in, Charset charset) {
        if (null == in) {
            return null;
        } else {
            InputStreamReader reader;
            if (null == charset) {
                reader = new InputStreamReader(in);
            } else {
                reader = new InputStreamReader(in, charset);
            }

            return new BufferedReader(reader);
        }
    }
	// 获得BufferedReader 如果是BufferedReader强转返回,否则新建。如果提供的Reader为null返回null
    public static BufferedReader getReader(Reader reader) {
        if (null == reader) {
            return null;
        } else {
            return reader instanceof BufferedReader ? (BufferedReader)reader : new BufferedReader(reader);
        }
    }
	// 获得PushbackReader 如果是PushbackReader强转返回,否则新建
    public static PushbackReader getPushBackReader(Reader reader, int pushBackSize) {
        return reader instanceof PushbackReader ? (PushbackReader)reader : new PushbackReader(reader, pushBackSize);
    }
	// 获得一个Writer,默认编码UTF-8
    public static OutputStreamWriter getUtf8Writer(OutputStream out) {
        return getWriter(out, CharsetUtil.CHARSET_UTF_8);
    }

    /** @deprecated */
    @Deprecated
    public static OutputStreamWriter getWriter(OutputStream out, String charsetName) {
        return getWriter(out, Charset.forName(charsetName));
    }
	// 获得一个Writer
    public static OutputStreamWriter getWriter(OutputStream out, Charset charset) {
        if (null == out) {
            return null;
        } else {
            return null == charset ? new OutputStreamWriter(out) : new OutputStreamWriter(out, charset);
        }
    }
	// 从流中读取UTF8编码的内容
    public static String readUtf8(InputStream in) throws IORuntimeException {
        return read(in, CharsetUtil.CHARSET_UTF_8);
    }

    /** @deprecated */
    @Deprecated
    public static String read(InputStream in, String charsetName) throws IORuntimeException {
        FastByteArrayOutputStream out = read(in);
        return StrUtil.isBlank(charsetName) ? out.toString() : out.toString(charsetName);
    }
	// 从流中读取内容,读取完成后关闭流
    public static String read(InputStream in, Charset charset) throws IORuntimeException {
        return StrUtil.str(readBytes(in), charset);
    }
	// 从流中读取内容,读到输出流中,读取完毕后关闭流
    public static FastByteArrayOutputStream read(InputStream in) throws IORuntimeException {
        return read(in, true);
    }
	// 从流中读取内容,读到输出流中,读取完毕后可选是否关闭流
    public static FastByteArrayOutputStream read(InputStream in, boolean isClose) throws IORuntimeException {
        FastByteArrayOutputStream out;
        if (in instanceof FileInputStream) {
            try {
                out = new FastByteArrayOutputStream(in.available());
            } catch (IOException var7) {
                throw new IORuntimeException(var7);
            }
        } else {
            out = new FastByteArrayOutputStream();
        }

        try {
            copy((InputStream)in, (OutputStream)out);
        } finally {
            if (isClose) {
                close(in);
            }

        }

        return out;
    }
	// 从Reader中读取String,读取完毕后关闭Reader
    public static String read(Reader reader) throws IORuntimeException {
        return read(reader, true);
    }
	// 从Reader中读取String 读取完毕后是否关闭Reader
    public static String read(Reader reader, boolean isClose) throws IORuntimeException {
        StringBuilder builder = StrUtil.builder();
        CharBuffer buffer = CharBuffer.allocate(8192);

        try {
            while(-1 != reader.read(buffer)) {
                builder.append(buffer.flip());
            }
        } catch (IOException var8) {
            throw new IORuntimeException(var8);
        } finally {
            if (isClose) {
                close(reader);
            }

        }

        return builder.toString();
    }
	// 从流中读取bytes,读取完毕后关闭流
    public static byte[] readBytes(InputStream in) throws IORuntimeException {
        return readBytes(in, true);
    }
	// 从流中读取bytes 是否关闭流
    public static byte[] readBytes(InputStream in, boolean isClose) throws IORuntimeException {
        if (!(in instanceof FileInputStream)) {
            return read(in, isClose).toByteArray();
        } else {
            byte[] result;
            try {
                int available = in.available();
                result = new byte[available];
                int readLength = in.read(result);
                if (readLength != available) {
                    throw new IOException(StrUtil.format("File length is [{}] but read [{}]!", new Object[]{available, readLength}));
                }
            } catch (IOException var8) {
                throw new IORuntimeException(var8);
            } finally {
                if (isClose) {
                    close(in);
                }

            }

            return result;
        }
    }
	// 读取指定长度的byte数组,不关闭流
    public static byte[] readBytes(InputStream in, int length) throws IORuntimeException {
        if (null == in) {
            return null;
        } else if (length <= 0) {
            return new byte[0];
        } else {
            FastByteArrayOutputStream out = new FastByteArrayOutputStream(length);
            copy((InputStream)in, (OutputStream)out, 8192, (long)length, (StreamProgress)null);
            return out.toByteArray();
        }
    }
	// 读取16进制字符串
    public static String readHex(InputStream in, int length, boolean toLowerCase) throws IORuntimeException {
        return HexUtil.encodeHexStr(readBytes(in, length), toLowerCase);
    }
	// 从流中读取前28个byte并转换为16进制,字母部分使用大写
    public static String readHex28Upper(InputStream in) throws IORuntimeException {
        return readHex(in, 28, false);
    }
	// 从流中读取前28个byte并转换为16进制,字母部分使用小写
    public static String readHex28Lower(InputStream in) throws IORuntimeException {
        return readHex(in, 28, true);
    }
	// 从流中读取对象,即对象的反序列化
    public static <T> T readObj(InputStream in) throws IORuntimeException, UtilException {
        return readObj((InputStream)in, (Class)null);
    }
	// 从流中读取对象,即对象的反序列化,读取后不关闭流
    public static <T> T readObj(InputStream in, Class<T> clazz) throws IORuntimeException, UtilException {
        try {
            return readObj(in instanceof ValidateObjectInputStream ? (ValidateObjectInputStream)in : new ValidateObjectInputStream(in, new Class[0]), clazz);
        } catch (IOException var3) {
            throw new IORuntimeException(var3);
        }
    }
	// 从流中读取对象,即对象的反序列化,读取后不关闭流
    public static <T> T readObj(ValidateObjectInputStream in, Class<T> clazz) throws IORuntimeException, UtilException {
        if (in == null) {
            throw new IllegalArgumentException("The InputStream must not be null");
        } else {
            if (null != clazz) {
                in.accept(new Class[]{clazz});
            }

            try {
                return in.readObject();
            } catch (IOException var3) {
                throw new IORuntimeException(var3);
            } catch (ClassNotFoundException var4) {
                throw new UtilException(var4);
            }
        }
    }
	// 从流中读取内容,使用UTF-8编码
    public static <T extends Collection<String>> T readUtf8Lines(InputStream in, T collection) throws IORuntimeException {
        return readLines(in, CharsetUtil.CHARSET_UTF_8, collection);
    }

    /** @deprecated */
    @Deprecated
    public static <T extends Collection<String>> T readLines(InputStream in, String charsetName, T collection) throws IORuntimeException {
        return readLines(in, CharsetUtil.charset(charsetName), collection);
    }
	// 从流中读取内容
    public static <T extends Collection<String>> T readLines(InputStream in, Charset charset, T collection) throws IORuntimeException {
        return readLines(getReader(in, charset), (Collection)collection);
    }
	// 从流中读取内容
    public static <T extends Collection<String>> T readLines(Reader reader, T collection) throws IORuntimeException {
        readLines(reader, collection::add);
        return collection;
    }
	// 从流中读取内容,使用UTF-8编码
    public static void readUtf8Lines(InputStream in, LineHandler lineHandler) throws IORuntimeException {
        readLines(in, CharsetUtil.CHARSET_UTF_8, lineHandler);
    }
	// 从流中读取内容
    public static void readLines(InputStream in, Charset charset, LineHandler lineHandler) throws IORuntimeException {
        readLines(getReader(in, charset), (LineHandler)lineHandler);
    }
	// 按行读取数据,针对每行的数据做处理 Reader自带编码定义,因此读取数据的编码跟随其编码。此方法不会关闭流,除非抛出异常
    public static void readLines(Reader reader, LineHandler lineHandler) throws IORuntimeException {
        Assert.notNull(reader);
        Assert.notNull(lineHandler);
        Iterator var2 = lineIter(reader).iterator();

        while(var2.hasNext()) {
            String line = (String)var2.next();
            lineHandler.handle(line);
        }

    }

    /** @deprecated */
    @Deprecated
    public static ByteArrayInputStream toStream(String content, String charsetName) {
        return toStream(content, CharsetUtil.charset(charsetName));
    }
	// String 转为流
    public static ByteArrayInputStream toStream(String content, Charset charset) {
        return content == null ? null : toStream(StrUtil.bytes(content, charset));
    }
	// String 转为UTF-8编码的字节流流
    public static ByteArrayInputStream toUtf8Stream(String content) {
        return toStream(content, CharsetUtil.CHARSET_UTF_8);
    }
	// 文件转为FileInputStream
    public static FileInputStream toStream(File file) {
        try {
            return new FileInputStream(file);
        } catch (FileNotFoundException var2) {
            throw new IORuntimeException(var2);
        }
    }
	// byte[] 转为ByteArrayInputStream
    public static ByteArrayInputStream toStream(byte[] content) {
        return content == null ? null : new ByteArrayInputStream(content);
    }
	// ByteArrayOutputStream转为ByteArrayInputStream
    public static ByteArrayInputStream toStream(ByteArrayOutputStream out) {
        return out == null ? null : new ByteArrayInputStream(out.toByteArray());
    }
	// 转换为BufferedInputStream
    public static BufferedInputStream toBuffered(InputStream in) {
        Assert.notNull(in, "InputStream must be not null!", new Object[0]);
        return in instanceof BufferedInputStream ? (BufferedInputStream)in : new BufferedInputStream(in);
    }
	// 转换为BufferedInputStream
    public static BufferedInputStream toBuffered(InputStream in, int bufferSize) {
        Assert.notNull(in, "InputStream must be not null!", new Object[0]);
        return in instanceof BufferedInputStream ? (BufferedInputStream)in : new BufferedInputStream(in, bufferSize);
    }
	// 转换为BufferedOutputStream
    public static BufferedOutputStream toBuffered(OutputStream out) {
        Assert.notNull(out, "OutputStream must be not null!", new Object[0]);
        return out instanceof BufferedOutputStream ? (BufferedOutputStream)out : new BufferedOutputStream(out);
    }
	// 转换为BufferedOutputStream
    public static BufferedOutputStream toBuffered(OutputStream out, int bufferSize) {
        Assert.notNull(out, "OutputStream must be not null!", new Object[0]);
        return out instanceof BufferedOutputStream ? (BufferedOutputStream)out : new BufferedOutputStream(out, bufferSize);
    }
	// 转换为BufferedReader
    public static BufferedReader toBuffered(Reader reader) {
        Assert.notNull(reader, "Reader must be not null!", new Object[0]);
        return reader instanceof BufferedReader ? (BufferedReader)reader : new BufferedReader(reader);
    }
	// 转换为BufferedReader
    public static BufferedReader toBuffered(Reader reader, int bufferSize) {
        Assert.notNull(reader, "Reader must be not null!", new Object[0]);
        return reader instanceof BufferedReader ? (BufferedReader)reader : new BufferedReader(reader, bufferSize);
    }
	// 转换为BufferedWriter
    public static BufferedWriter toBuffered(Writer writer) {
        Assert.notNull(writer, "Writer must be not null!", new Object[0]);
        return writer instanceof BufferedWriter ? (BufferedWriter)writer : new BufferedWriter(writer);
    }
	// 转换为BufferedWriter
    public static BufferedWriter toBuffered(Writer writer, int bufferSize) {
        Assert.notNull(writer, "Writer must be not null!", new Object[0]);
        return writer instanceof BufferedWriter ? (BufferedWriter)writer : new BufferedWriter(writer, bufferSize);
    }
	// 将InputStream转换为支持mark标记的流 若原流支持mark标记,则返回原流,否则使用BufferedInputStream 包装之
    public static InputStream toMarkSupportStream(InputStream in) {
        if (null == in) {
            return null;
        } else {
            return (InputStream)(!in.markSupported() ? new BufferedInputStream(in) : in);
        }
    }
	// 转换为PushbackInputStream 如果传入的输入流已经是PushbackInputStream,强转返回,否则新建一个
    public static PushbackInputStream toPushbackStream(InputStream in, int pushBackSize) {
        return in instanceof PushbackInputStream ? (PushbackInputStream)in : new PushbackInputStream(in, pushBackSize);
    }
	// 将指定InputStream 转换为InputStream.available()方法可用的流。在Socket通信流中,服务端未返回数据情况下InputStream.available()方法始终为0因此,在读取前需要调用InputStream.read()读取一个字节(未返回会阻塞),一旦读取到了,InputStream.available()方法就正常了。需要注意的是,在网络流中,是按照块来传输的,所以 InputStream.available() 读取到的并非最终长度,而是此次块的长度。此方法返回对象的规则为:FileInputStream 返回原对象,因为文件流的available方法本身可用其它InputStream 返回PushbackInputStream
    public static InputStream toAvailableStream(InputStream in) {
        if (in instanceof FileInputStream) {
            return in;
        } else {
            PushbackInputStream pushbackInputStream = toPushbackStream(in, 1);

            try {
                int available = pushbackInputStream.available();
                if (available <= 0) {
                    int b = pushbackInputStream.read();
                    pushbackInputStream.unread(b);
                }

                return pushbackInputStream;
            } catch (IOException var4) {
                throw new IORuntimeException(var4);
            }
        }
    }
	// 将byte[]写到流中
    public static void write(OutputStream out, boolean isCloseOut, byte[] content) throws IORuntimeException {
        try {
            out.write(content);
        } catch (IOException var7) {
            throw new IORuntimeException(var7);
        } finally {
            if (isCloseOut) {
                close(out);
            }

        }

    }
	// 将多部分内容写到流中,自动转换为UTF-8字符串
    public static void writeUtf8(OutputStream out, boolean isCloseOut, Object... contents) throws IORuntimeException {
        write(out, CharsetUtil.CHARSET_UTF_8, isCloseOut, contents);
    }

    /** @deprecated */
    @Deprecated
    public static void write(OutputStream out, String charsetName, boolean isCloseOut, Object... contents) throws IORuntimeException {
        write(out, CharsetUtil.charset(charsetName), isCloseOut, contents);
    }
	// 将多部分内容写到流中,自动转换为字符串
    public static void write(OutputStream out, Charset charset, boolean isCloseOut, Object... contents) throws IORuntimeException {
        OutputStreamWriter osw = null;

        try {
            osw = getWriter(out, charset);
            Object[] var5 = contents;
            int var6 = contents.length;

            for(int var7 = 0; var7 < var6; ++var7) {
                Object content = var5[var7];
                if (content != null) {
                    osw.write(Convert.toStr(content, ""));
                }
            }

            osw.flush();
        } catch (IOException var12) {
            throw new IORuntimeException(var12);
        } finally {
            if (isCloseOut) {
                close(osw);
            }

        }

    }
	// 将多部分内容写到流中
    public static void writeObj(OutputStream out, boolean isCloseOut, Serializable obj) throws IORuntimeException {
        writeObjects(out, isCloseOut, obj);
    }
	// 将多部分内容写到流中
    public static void writeObjects(OutputStream out, boolean isCloseOut, Serializable... contents) throws IORuntimeException {
        ObjectOutputStream osw = null;

        try {
            osw = out instanceof ObjectOutputStream ? (ObjectOutputStream)out : new ObjectOutputStream(out);
            Serializable[] var4 = contents;
            int var5 = contents.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                Object content = var4[var6];
                if (content != null) {
                    osw.writeObject(content);
                }
            }

            osw.flush();
        } catch (IOException var11) {
            throw new IORuntimeException(var11);
        } finally {
            if (isCloseOut) {
                close(osw);
            }

        }
    }
	// 从缓存中刷出数据
    public static void flush(Flushable flushable) {
        if (null != flushable) {
            try {
                flushable.flush();
            } catch (Exception var2) {
            }
        }

    }
	// 关闭失败不会抛出异常
    public static void close(Closeable closeable) {
        if (null != closeable) {
            try {
                closeable.close();
            } catch (Exception var2) {
            }
        }

    }
	// 尝试关闭指定对象判断对象如果实现了AutoCloseable,则调用之
    public static void closeIfPosible(Object obj) {
        if (obj instanceof AutoCloseable) {
            close((AutoCloseable)obj);
        }

    }
	// 对比两个流内容是否相同 内部会转换流为 BufferedInputStream
    public static boolean contentEquals(InputStream input1, InputStream input2) throws IORuntimeException {
        if (!(input1 instanceof BufferedInputStream)) {
            input1 = new BufferedInputStream((InputStream)input1);
        }

        if (!(input2 instanceof BufferedInputStream)) {
            input2 = new BufferedInputStream((InputStream)input2);
        }

        try {
            int ch2;
            for(int ch = ((InputStream)input1).read(); -1 != ch; ch = ((InputStream)input1).read()) {
                ch2 = ((InputStream)input2).read();
                if (ch != ch2) {
                    return false;
                }
            }

            ch2 = ((InputStream)input2).read();
            return ch2 == -1;
        } catch (IOException var4) {
            throw new IORuntimeException(var4);
        }
    }
	// 对比两个Reader的内容是否一致 内部会转换流为 BufferedInputStream
    public static boolean contentEquals(Reader input1, Reader input2) throws IORuntimeException {
        Reader input1 = getReader(input1);
        BufferedReader input2 = getReader(input2);

        try {
            int ch2;
            for(int ch = input1.read(); -1 != ch; ch = input1.read()) {
                ch2 = input2.read();
                if (ch != ch2) {
                    return false;
                }
            }

            ch2 = input2.read();
            return ch2 == -1;
        } catch (IOException var4) {
            throw new IORuntimeException(var4);
        }
    }
	// 对比两个流内容是否相同,忽略EOL字符 内部会转换流为 BufferedInputStream
    public static boolean contentEqualsIgnoreEOL(Reader input1, Reader input2) throws IORuntimeException {
        BufferedReader br1 = getReader(input1);
        BufferedReader br2 = getReader(input2);

        try {
            String line1 = br1.readLine();

            String line2;
            for(line2 = br2.readLine(); line1 != null && line1.equals(line2); line2 = br2.readLine()) {
                line1 = br1.readLine();
            }

            return Objects.equals(line1, line2);
        } catch (IOException var6) {
            throw new IORuntimeException(var6);
        }
    }
	// 计算流CRC32校验码,计算后关闭流
    public static long checksumCRC32(InputStream in) throws IORuntimeException {
        return checksum(in, new CRC32()).getValue();
    }
	// 计算流的校验码,计算后关闭流
    public static Checksum checksum(InputStream in, Checksum checksum) throws IORuntimeException {
        Assert.notNull(in, "InputStream is null !", new Object[0]);
        if (null == checksum) {
            checksum = new CRC32();
        }

        try {
            in = new CheckedInputStream((InputStream)in, (Checksum)checksum);
            copy((InputStream)in, (OutputStream)(new NullOutputStream()));
        } finally {
            close((Closeable)in);
        }

        return (Checksum)checksum;
    }
	// 计算流的校验码,计算后关闭流
    public static long checksumValue(InputStream in, Checksum checksum) {
        return checksum(in, checksum).getValue();
    }
	// 返回行遍历器
    public static LineIter lineIter(Reader reader) {
        return new LineIter(reader);
    }
	// 返回行遍历器
    public static LineIter lineIter(InputStream in, Charset charset) {
        return new LineIter(in, charset);
    }
	// ByteArrayOutputStream 转换为String
    public static String toStr(ByteArrayOutputStream out, Charset charset) {
        try {
            return out.toString(charset.name());
        } catch (UnsupportedEncodingException var3) {
            throw new IORuntimeException(var3);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听不见你的名字

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值