hutool工具类的DateUtil和LocalDateTimeUtil

目录

java中的Date和LocalDateTime的区别

1.1 设计理念

1.2 功能和特性

1.3 线程安全性

1.4 使用场景

2.1 MySQL 的 DATETIME 类型

2.2 映射关系

 hutool工具类的DateUtil和LocalDatetimeUtil工具类

DateUtil使用

LocalDatetimeUtil使用


java中的Date和LocalDateTime的区别

1.1 设计理念

  • java.time.LocalDateTime

    • 是 Java 8 引入的 java.time 包中的一个类,属于新的日期时间 API(JSR-310)。

    • 它是不可变的、线程安全的,并且专注于本地日期和时间(不包含时区信息)。

    • 设计上更加灵活,提供了丰富的日期时间操作方法,如日期加减、格式化等。

  • java.util.Date

    • 是 Java 早期的日期时间类,存在于 Java 1.0 中。

    • 它是一个可变类,线程不安全。

    • 同时包含日期和时间信息,但功能较为有限,且存在一些设计上的缺陷(如月份从 0 开始)。

1.2 功能和特性

  • LocalDateTime

    • 不包含时区信息,只表示本地日期和时间。

    • 提供了丰富的日期时间操作方法,例如 plusDays()minusHours()format() 等。

    • 可以与 java.time.ZoneId 结合使用,转换为带时区的日期时间(如 ZonedDateTime)。

    • 支持 ISO-8601 标准日期时间格式。

  • Date

    • 包含自 1970-01-01 00:00:00 GMT 以来的毫秒数(时间戳)。

    • 提供的方法较少,且存在一些易用性问题(如月份从 0 开始)。

    • 可以通过 SimpleDateFormat 进行格式化,但 SimpleDateFormat 是线程不安全的。

1.3 线程安全性

  • LocalDateTime:不可变,线程安全。

  • Date:可变,线程不安全。

1.4 使用场景

  • LocalDateTime:推荐在需要精确日期时间操作、格式化或需要与 Java 8 及以上版本的新日期时间 API 集成的场景中使用。

  • Date:在一些旧的 Java 应用或需要与旧版本 Java 代码兼容的场景中仍然会用到,但不推荐在新项目中使用。

 

2.1 MySQL 的 DATETIME 类型

  • DATETIME 是 MySQL 中用于存储日期和时间的字段类型,格式为 YYYY-MM-DD HH:MM:SS

  • 它不包含时区信息,只表示本地日期和时间。

2.2 映射关系

  • LocalDateTime

    • LocalDateTime 与 MySQL 的 DATETIME 类型字段天然匹配,因为它们都表示本地日期和时间,且不包含时区信息。

    • 在使用 JPA、Hibernate 或 MyBatis 等框架时,LocalDateTime 可以直接映射到 DATETIME 字段。

  • Date

    • Date 也可以映射到 MySQL 的 DATETIME 类型字段,但需要注意以下几点:

      1. Date 包含时间戳(毫秒数),在存储到数据库时,通常需要转换为 java.sql.Timestampjava.sql.Date

      2. Date 的月份从 0 开始,可能会导致混淆。

      3. 如果使用 Date,建议在存储和读取时进行显式的转换。

@Temporal(TemporalType.TIMESTAMP) // 需要指定时间类型
    private Date eventTime; // 映射到 DATETIME

 hutool工具类的DateUtil和LocalDatetimeUtil工具类

DateUtil工具类可以操作Date类型数据, LocalDatetimeUtil工具类可以操作 LocalDatetime类型数据。

接收前端的时间参数可以使用@JsonFormat注解指定序列化和反序列化的时间格式

 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime estimatedStartTime;

DateUtil使用

传入的时间格式是字符串类型

    @GetMapping("count")
    @ApiOperation(value = "任务数量查询", notes = "按照当日快递员id列表查询每个快递员的取派件任务数")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "courierIds", value = "订单id列表", required = true),
            @ApiImplicitParam(name = "taskType", value = "任务类型", required = true),
            @ApiImplicitParam(name = "date", value = "日期,格式:yyyy-MM-dd 或 yyyyMMdd", required = true)
    })
    public List<CourierTaskCountDTO> findCountByCourierIds(@RequestParam("courierIds") List<Long> courierIds,
                                                           @RequestParam("taskType") PickupDispatchTaskType taskType,
                                                           @RequestParam("date") String date) {
        return this.pickupDispatchTaskService.findCountByCourierIds(courierIds, taskType, date);

这里可以直接使用DateUtil工具类的parse方法解析这个日期字符串对象,我们进入源码查看,可以发现可以解析四种类型的数据

也可以自定义解析格式

DateTime dateTime = DateUtil.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));

 可以发现返回类型是hutool工具类的DateTime类型,这个类继承了Date类

这两个方法可以这个时间的0点时间和结束时间

LocalDateTime beginTime = DateUtil.beginOfDay(dateTime).toLocalDateTime();
        LocalDateTime endTime = DateUtil.endOfDay(dateTime).toLocalDateTime();

    @Override
    public List<CourierTaskCountDTO> findCountByCourierIds(List<Long> courierIds, PickupDispatchTaskType pickupDispatchTaskType, String date) {
        // TODO day09 查询指定快递员的任务数量

        //1. 计算一天的时间的边界  tips: 使用hutool 的 DateUtil
        DateTime dateTime = DateUtil.parse(date);
        LocalDateTime beginTime = DateUtil.beginOfDay(dateTime).toLocalDateTime();
        LocalDateTime endTime = DateUtil.endOfDay(dateTime).toLocalDateTime();
        //2. 执行SQL  tips: 下面是sql提示 需要写到TaskPickupDispatchMapper中
        // SELECT
        //        COUNT(1) `count`,
        //            courier_id
        //        FROM sl_pickup_dispatch_task t
        //        WHERE
        //            t.courier_id IN  <foreach collection="courierIds" item="courierId" open="(" close=")" separator=",">#{courierId}</foreach>
        //        AND t.created BETWEEN #{startDateTime} AND #{endDateTime}
        //        AND t.task_type = #{type}
        //        GROUP BY courier_id
        return taskPickupDispatchMapper.findCountByCourierIds(courierIds, pickupDispatchTaskType.getCode(), beginTime, endTime);
    }

解析成功

 

LocalDateTime startTime = LocalDateTimeUtil.of(DateUtil.beginOfDay(new Date()));
        LocalDateTime endTime = LocalDateTimeUtil.of(DateUtil.endOfDay(new Date())); 

/**
     * 今日任务分类计数
     *
     * @param courierId 快递员id
     * @param taskType  任务类型,1为取件任务,2为派件任务
     * @param status    任务状态,1新任务,2已完成,3已取消
     * @param isDeleted 是否逻辑删除
     * @return 任务数量
     */
    @Override
    public Integer todayTasksCount(Long courierId, PickupDispatchTaskType taskType, PickupDispatchTaskStatus status, PickupDispatchTaskIsDeleted isDeleted) {
        //构建查询条件
        LambdaQueryWrapper<PickupDispatchTaskEntity> queryWrapper = Wrappers.<PickupDispatchTaskEntity>lambdaQuery()
                .eq(ObjectUtil.isNotEmpty(courierId), PickupDispatchTaskEntity::getCourierId, courierId)
                .eq(ObjectUtil.isNotEmpty(taskType), PickupDispatchTaskEntity::getTaskType, taskType)
                .eq(ObjectUtil.isNotEmpty(status), PickupDispatchTaskEntity::getStatus, status)
                .eq(ObjectUtil.isNotEmpty(isDeleted), PickupDispatchTaskEntity::getIsDeleted, isDeleted);
        //根据任务状态限定查询的日期条件
        LocalDateTime startTime = LocalDateTimeUtil.of(DateUtil.beginOfDay(new Date()));
        LocalDateTime endTime = LocalDateTimeUtil.of(DateUtil.endOfDay(new Date()));
        if (status == null) {
            //没有任务状态,查询任务创建时间
            queryWrapper.between(PickupDispatchTaskEntity::getCreated, startTime, endTime);
        } else if (status == PickupDispatchTaskStatus.NEW) {
            //新任务状态,查询预计结束时间
            queryWrapper.between(PickupDispatchTaskEntity::getEstimatedEndTime, startTime, endTime);
        } else if (status == PickupDispatchTaskStatus.COMPLETED) {
            //完成状态,查询实际完成时间
            queryWrapper.between(PickupDispatchTaskEntity::getActualEndTime, startTime, endTime);
        } else if (status == PickupDispatchTaskStatus.CANCELLED) {
            //取消状态,查询取消时间
            queryWrapper.between(PickupDispatchTaskEntity::getCancelTime, startTime, endTime);
        }
        //结果返回integer类型值
        return Convert.toInt(super.count(queryWrapper));
    }

LocalDatetimeUtil使用

    @Override
    public List<PickupDispatchTaskDTO> findTodayTaskByCourierId(Long courierId) {
       

        // 1. 构建查询条件
        LambdaQueryWrapper<PickupDispatchTaskEntity> wrapper = Wrappers.<PickupDispatchTaskEntity>lambdaQuery()
                .eq(PickupDispatchTaskEntity::getCourierId, courierId)
                .ge(PickupDispatchTaskEntity::getEstimatedStartTime, LocalDateTimeUtil.beginOfDay(LocalDateTime.now()))
                .le(PickupDispatchTaskEntity::getEstimatedStartTime, LocalDateTimeUtil.endOfDay(LocalDateTime.now()))
                .eq(PickupDispatchTaskEntity::getIsDeleted, PickupDispatchTaskIsDeleted.NOT_DELETED);
        // 1.1 快递员id 等值查询
        // 1.2 预计开始时间 大于等于今天的开始时间  今天 00:00:00
        // 1.3 预计开始时间 小于等于今天的结束时间  今天 23:59:59
        // 1.4 isDeleted 不能是删除状态
        // 2. 执行查询
        // 3. 将entity集合 转为 DTO集合返回   tips: BeanUtil
        List<PickupDispatchTaskEntity> list = super.list(wrapper);
        return BeanUtil.copyToList(list, PickupDispatchTaskDTO.class);
    }

package com.aapoint.util; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAdjusters; public class LocalDateTimeUtil { /** * 比较 localDateTime2 是否在localDateTime1之前(比较大小) * @param localDateTime1 * @param localDateTime2 * @return */ public static Boolean compare(LocalDateTime localDateTime1,LocalDateTime localDateTime2){ return localDateTime1.isBefore(localDateTime2); } /** * 获取当前月份前/后的月份的第一天 * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String firstDay(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,0,i); //获取该月份的第一天 String firstDay = date.with(TemporalAdjusters.firstDayOfMonth()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // System.out.println("第一天为:"+firstDay); return firstDay; } /** * 获取当前月份前/后的月份的最后一天 * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String lastDay(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,0,i); //获取该月份的最后一天 String lastDay = date.with(TemporalAdjusters.lastDayOfMonth()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // System.out.println("最后一天为:"+lastDay); return lastDay; } /** * 获取当时间前/后的时间(天) * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String obtainDay(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,1,i); //获取天 String day = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // System.out.println("获取的时间为(天):"+day); return day; } /** * 获取当时间前/后的时间(小时) * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String obtainHours(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,2,i); //获取该月份的最后一天 String hours = date.format(DateTimeFormatter.ofPattern("HH:mm:ss")); // System.out.println("获取的时间为(小时):"+hours); return hours; } /** * 获取当时间前/后的时间(小时) * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String obtainMinutes(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,3,i); //获取该月份的最后一天 String minutes = date.format(DateTimeFormatter.ofPattern("HH:mm:ss")); // System.out.println("获取的时间为(分钟):"+minutes); return minutes; } /** * 获取当时间前/后的时间(小时) * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String obtainSeconds(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,4,i); //获取该月份的最后一天 String seconds = date.format(DateTimeFormatter.ofPattern("HH:mm:ss")); // System.out.println("获取的时间为(秒):"+seconds); return seconds; } public static void main(String[] args) { System.out.println("当前时间为:"+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); System.out.println("前一个月份的第一天为:"+LocalDateTimeUtil.firstDay(1,1)); System.out.println("前一个月份的最后一天为:"+LocalDateTimeUtil.lastDay(1,1)); System.out.println("当前时间的前一天为:"+LocalDateTimeUtil.obtainDay(1,1)); System.out.println("当前时间的后一天为:"+LocalDateTimeUtil.obtainDay(2,1)); System.out.println("当前时间的前一小时为:"+LocalDateTimeUtil.obtainHours(1,1)); System.out.println("当前时间的后一小时为:"+LocalDateTimeUtil.obtainHours(2,1)); System.out.println("当前时间的前一分钟为:"+LocalDateTimeUtil.obtainMinutes(1,1)); System.out.println("当前时间的后一分钟为:"+LocalDateTimeUtil.obtainMinutes(2,1)); System.out.println("当前时间的前一秒为:"+LocalDateTimeUtil.obtainSeconds(1,1)); System.out.println("当前时间的后一秒为:"+LocalDateTimeUtil.obtainSeconds(2,1)); } private static LocalDateTime getLocalDateTime(Integer state,Integer type,Integer i) { LocalDateTime date; if(state == 0){ date = LocalDateTime.now(); }else if(state == 1){ if(type == 0) { //获取月 date = LocalDateTime.now().minusMonths(i); }else if(type == 1){ //获取天 date = LocalDateTime.now().minusDays(i); }else if(type == 2){ //获取小时 date = LocalDateTime.now().minusHours(i); }else if(type == 3){ //获取分钟 date = LocalDateTime.now().minusMinutes(i);
<think>嗯,用户想找Hutool工具类中与日期格式相关的常量定义。首先,我得回忆一下Hutool的文档结构。根据提供的引用内容,引用[3]里提到了Hutool的时间日期处理部分,比如DateUtil类,还有字符串工具StrUtil。用户可能需要具体的日期格式常量,比如常见的yyyy-MM-dd这种。 然后,查看引用里的信息,引用[3]中的“四、工具类”下提到了DateUtil,并列举了日期转换的方法,比如格式化输出、获取日期部分等。但问题在于用户问的是常量定义,也就是Hutool是否预定义了常用的日期格式字符串,避免每次都手动输入。 接下来,我需要确认Hutool是否有这样的常量类。通常,这类工具库会有类似DatePattern的类,里面包含各种格式常量。例如,DatePattern.NORM_DATE_FORMAT对应"yyyy-MM-dd"。根据引用[3]中的内容,虽然没直接提到DatePattern,但引用了DateUtil.format方法的使用,其中可能用到这些常量。 此外,引用[2]中的例子显示使用DateUtil.formatTime(date)返回"00:00:00",说明有时间格式的常量可能存在。用户可能需要知道这些常量的具体名称对应的格式字符串。 然后,根据Hutool的官方文档(引用[4]),应该有一个DatePattern类,里面定义了各种格式常量。需要检查引用中的内容是否有相关描述。在引用[3]的目录里,第四部分工具类中的“字符串工具-StrUtil”提到了标点符号字符串常量定义,但日期格式可能在DateUtil或专门的常量类中。 因此,总结回答:Hutool的日期格式常量通常在DatePattern类中定义,包含如NORM_DATE_FORMAT、NORM_DATETIME_FORMAT等。需要列出这些常量及其对应的格式,并建议用户参考官方文档或源码中的DatePattern类。同时,提醒用户注意不同Hutool版本的差异,建议查阅对应版本的文档。</think>### Hutool日期格式常量定义说明 Hutool工具包中与**日期格式相关的常量**主要通过`DatePattern`类定义,该类位于`cn.hutool.core.date`包下。以下是常见的日期格式常量定义列表及对应格式说明: --- #### 1. **标准格式常量** | 常量名称 | 格式 | 示例 | |---------|------|------| | `NORM_DATE_PATTERN` | `yyyy-MM-dd` | 2023-10-01 | | `NORM_TIME_PATTERN` | `HH:mm:ss` | 14:30:00 | | `NORM_DATETIME_PATTERN` | `yyyy-MM-dd HH:mm:ss` | 2023-10-01 14:30:00 | | `NORM_DATETIME_MINUTE_PATTERN` | `yyyy-MM-dd HH:mm` | 2023-10-01 14:30 | | `NORM_DATETIME_MS_PATTERN` | `yyyy-MM-dd HH:mm:ss.SSS` | 2023-10-01 14:30:00.123 | --- #### 2. **其他常用格式** | 常量名称 | 格式 | 示例 | |---------|------|------| | `UTC_SIMPLE_PATTERN` | `yyyy-MM-dd'T'HH:mm:ss` | 2023-10-01T14:30:00 | | `UTC_PATTERN` | `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'` | 2023-10-01T14:30:00.123Z | | `CHINESE_DATE_PATTERN` | `yyyy年MM月dd日` | 2023年10月01日 | | `PURE_DATE_PATTERN` | `yyyyMMdd` | 20231001 | | `PURE_TIME_PATTERN` | `HHmmss` | 143000 | | `PURE_DATETIME_PATTERN` | `yyyyMMddHHmmss` | 20231001143000 | | `PURE_DATETIME_MS_PATTERN` | `yyyyMMddHHmmssSSS` | 20231001143000123 | --- #### 3. **使用方法示例** ```java // 使用预定义常量格式化日期 Date date = DateUtil.date(); String dateStr = DateUtil.format(date, DatePattern.NORM_DATETIME_PATTERN); System.out.println(dateStr); // 输出:2023-10-01 14:30:00 // 解析日期字符串 String input = "2023年10月01日"; Date parsedDate = DateUtil.parse(input, DatePattern.CHINESE_DATE_PATTERN); ``` --- #### 4. **注意事项** - **版本差异**:不同Hutool版本可能新增或调整格式常量,建议查阅对应版本的官方文档[^4]。 - **扩展性**:若需自定义格式,可直接传入格式字符串,无需依赖预定义常量[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

落落落sss

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

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

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

打赏作者

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

抵扣说明:

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

余额充值