# 一.基本介绍
# 1.Hutool DateUtil 优点
Hutool 是一个 Java 工具包,提供了丰富的工具方法,用于简化 Java 开发过程中的常见任务。DateUtil 是 Hutool 中的日期工具类,它具有以下优点:
- 简单易用:DateUtil 提供了大量的静态方法,可以方便地进行日期的格式化、解析、比较、计算等操作,使用起来非常简单。
- 功能丰富:DateUtil 支持多种日期格式的解析和格式化,可以处理常见的日期操作,比如日期比较、日期计算、日期加减、日期格式化等。
- 高效性能:Hutool 的设计注重性能优化,DateUtil 的方法经过优化,执行效率高,可以提高应用程序的性能。
- 可扩展性:Hutool 提供了丰富的工具类和接口,可以根据需求自定义扩展,满足不同开发场景的需求。
Hutool 的 DateUtil 是一个功能强大、简单易用、高性能的日期工具类,可以方便地处理日期相关的操作。
# 2.注意事项
对于 hutool 的 DateUtil,需要注意以下事项:
- 引入 hutool 包:在使用 DateUtil 之前,需要先引入 hutool 的相关包,可以通过 Maven 或者 Gradle 等方式进行引入。
- 日期格式的正确性:在使用 DateUtil 进行日期的解析和格式化时,需要确保日期格式的正确性,否则可能会导致解析失败或者格式化结果不符合预期。
- 时区的设置:如果涉及到时区的问题,需要注意在使用 DateUtil 之前,设置好正确的时区,以避免日期计算和转换时出现错误。
- 线程安全性:hutool 的 DateUtil 是线程安全的,可以在多线程环境下使用,无需额外的同步处理。
# 3.引入依赖
<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-core</artifactId>
  <version>5.6.5</version>
</dependency>
2
3
4
5
# 二.DateUtil 概览
# 1.truncate
修改日期为某个时间字段起始时间
String dateStr2 = "2020-02-29 12:59:34";
Date date2 = DateUtil.parse(dateStr2);
final DateTime dateTime = DateUtil.truncate(date2, DateField.MINUTE);
Assert.assertEquals("2020-02-29 12:59:00", dateTime.toString());
2
3
4
# 2.round
修改日期为某个时间字段四舍五入时间
String dateStr2 = "2020-02-29 12:59:34";
Date date2 = DateUtil.parse(dateStr2);
DateTime dateTime = DateUtil.round(date2, DateField.MINUTE);
Assert.assertEquals("2020-02-29 12:59:59", dateTime.toString());
dateStr2 = "2020-02-29 12:05:29";
date2 = DateUtil.parse(dateStr2);
dateTime = DateUtil.round(date2, DateField.MINUTE);
Assert.assertEquals("2020-02-29 12:05:00", dateTime.toString());
2
3
4
5
6
7
8
9
# 3.ceiling
修改日期为某个时间字段结束时间
String dateStr2 = "2020-02-29 12:59:34";
Date date2 = DateUtil.parse(dateStr2);
DateTime dateTime = DateUtil.ceiling(date2, DateField.MINUTE);
Assert.assertEquals("2020-02-29 12:59:59", dateTime.toString());
2
3
4
# 4.beginOfSecond
获取秒级别的开始时间,即忽略毫秒部分
@Test
public void test04() {
    String dateStr2 = "2021-05-16 22:50:34.111";
    Date date2 = DateUtil.parse(dateStr2);
    DateTime dateTime = DateUtil.beginOfSecond(date2);
    Assert.assertEquals("2021-05-16 22:50:34", dateTime.toString());
}
2
3
4
5
6
7
# 5.endOfSecond
获取秒级别的结束时间,即毫秒设置为 999
@Test
public void test05() {
    String dateStr2 = "2021-05-16 22:50:34.111";
    DateTime date2 = DateUtil.parse(dateStr2, "yyyy-MM-dd HH:mm:ss.SSS");
    int millisecond = DateUtil.millisecond(date2);
    System.out.println(millisecond);
    DateTime dateTime = DateUtil.endOfSecond(date2);
    Assert.assertEquals(999, DateUtil.millisecond(dateTime));
}
2
3
4
5
6
7
8
9
# 6.beginOfHour
获取某小时的开始时间
@Test
public void test06() {
    String dateStr2 = "2021-05-16 22:50:34.111";
    DateTime date2 = DateUtil.parse(dateStr2, "yyyy-MM-dd HH:mm:ss.SSS");
    DateTime dateTime = DateUtil.beginOfHour(date2);
    System.out.println(dateTime);
    Assert.assertEquals("2021-05-16 22:00:00", dateTime.toString());
}
2
3
4
5
6
7
8
# 7.endOfHour
获取某小时的结束时间
@Test
public void test07() {
  String dateStr2 = "2021-05-16 22:50:34.111";
  DateTime date2 = DateUtil.parse(dateStr2, "yyyy-MM-dd HH:mm:ss.SSS");
  DateTime dateTime = DateUtil.endOfHour(date2);
  Assert.assertEquals("2021-05-16 22:59:59", dateTime.toString());
}
2
3
4
5
6
7
# 8.beginOfMinute
获取某分钟的开始时间
@Test
public void test08() {
    String dateStr2 = "2021-05-16 22:50:34.111";
    DateTime date2 = DateUtil.parse(dateStr2, "yyyy-MM-dd HH:mm:ss.SSS");
    DateTime dateTime = DateUtil.beginOfMinute(date2);
    Assert.assertEquals("2021-05-16 22:50:00", dateTime.toString());
}
2
3
4
5
6
7
# 9.endOfMinute
获取某分钟的结束时间
@Test
public void test09() {
    String dateStr2 = "2021-05-16 22:50:34.111";
    DateTime date2 = DateUtil.parse(dateStr2, "yyyy-MM-dd HH:mm:ss.SSS");
    DateTime dateTime = DateUtil.endOfMinute(date2);
    Assert.assertEquals("2021-05-16 22:50:59", dateTime.toString());
}
2
3
4
5
6
7
# 10.beginOfDay
获取某天的开始时间
@Test
public void test10() {
  String dateStr = "2017-03-01 00:33:23";
  Date date = DateUtil.parse(dateStr);
  // 一天的开始
  Date beginOfDay = DateUtil.beginOfDay(date);
  Assert.assertEquals("2017-03-01 00:00:00", beginOfDay.toString());
  // 一天的结束
  Date endOfDay = DateUtil.endOfDay(date);
  Assert.assertEquals("2017-03-01 23:59:59", endOfDay.toString());
}
2
3
4
5
6
7
8
9
10
11
12
# 11.endOfDay
获取某天的结束时间
@Test
public void test11() {
  String dateStr = "2017-03-01 00:33:23";
  Date date = DateUtil.parse(dateStr);
  // 一天的开始
  Date beginOfDay = DateUtil.beginOfDay(date);
  Assert.assertEquals("2017-03-01 00:00:00", beginOfDay.toString());
  // 一天的结束
  Date endOfDay = DateUtil.endOfDay(date);
  Assert.assertEquals("2017-03-01 23:59:59", endOfDay.toString());
}
2
3
4
5
6
7
8
9
10
11
12
# 12.beginOfWeek
获取某周的开始时间,周一定为一周的开始时间
@Test
public void test12() {
    String dateStr = "2017-03-01 22:33:23";
    DateTime date = DateUtil.parse(dateStr);
    Objects.requireNonNull(date).setFirstDayOfWeek(Week.MONDAY);
    // 一周的开始
    Date beginOfWeek = DateUtil.beginOfWeek(date);
    Assert.assertEquals("2017-02-27 00:00:00", beginOfWeek.toString());
    // 一周的结束
    Date endOfWeek = DateUtil.endOfWeek(date);
    Assert.assertEquals("2017-03-05 23:59:59", endOfWeek.toString());
    Calendar calendar = DateUtil.calendar(date);
    // 一周的开始
    Calendar begin = DateUtil.beginOfWeek(calendar);
    Assert.assertEquals("2017-02-27 00:00:00", DateUtil.date(begin).toString());
    // 一周的结束
    Calendar end = DateUtil.endOfWeek(calendar);
    Assert.assertEquals("2017-03-05 23:59:59", DateUtil.date(end).toString());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cn.hutool.core.date.DateUtil.beginOfWeek(java.util.Date, boolean)
isMondayAsFirstDay 是否周一做为一周的第一天(false 表示周日做为第一天)
@Test
public void test13() {
  String beginStr = "2020-03-11";
  DateTime date = DateUtil.parseDate(beginStr);
  Calendar calendar = date.toCalendar();
  final Calendar begin = DateUtil.beginOfWeek(calendar, false);
  Assert.assertEquals("2020-03-08 00:00:00", DateUtil.date(begin).toString());
  Calendar calendar2 = date.toCalendar();
  final Calendar end = DateUtil.endOfWeek(calendar2, false);
  Assert.assertEquals("2020-03-14 23:59:59", DateUtil.date(end).toString());
}
2
3
4
5
6
7
8
9
10
11
12
# 13.endOfWeek
获取某周的结束时间,周日定为一周的结束
@Test
public void test14() {
  String dateStr = "2017-03-01 22:33:23";
  DateTime date = DateUtil.parse(dateStr);
  Objects.requireNonNull(date).setFirstDayOfWeek(Week.MONDAY);
  // 一周的开始
  Date beginOfWeek = DateUtil.beginOfWeek(date);
  Assert.assertEquals("2017-02-27 00:00:00", beginOfWeek.toString());
  // 一周的结束
  Date endOfWeek = DateUtil.endOfWeek(date);
  Assert.assertEquals("2017-03-05 23:59:59", endOfWeek.toString());
  Calendar calendar = DateUtil.calendar(date);
  // 一周的开始
  Calendar begin = DateUtil.beginOfWeek(calendar);
  Assert.assertEquals("2017-02-27 00:00:00", DateUtil.date(begin).toString());
  // 一周的结束
  Calendar end = DateUtil.endOfWeek(calendar);
  Assert.assertEquals("2017-03-05 23:59:59", DateUtil.date(end).toString());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cn.hutool.core.date.DateUtil.endOfWeek(java.util.Date, boolean)
isSundayAsLastDay 是否周日做为一周的最后一天(false 表示周六做为最后一天)
@Test
public void test15() {
  String beginStr = "2020-03-11";
  DateTime date = DateUtil.parseDate(beginStr);
  Calendar calendar = date.toCalendar();
  final Calendar begin = DateUtil.beginOfWeek(calendar, false);
  Assert.assertEquals("2020-03-08 00:00:00", DateUtil.date(begin).toString());
  Calendar calendar2 = date.toCalendar();
  final Calendar end = DateUtil.endOfWeek(calendar2, false);
  Assert.assertEquals("2020-03-14 23:59:59", DateUtil.date(end).toString());
}
2
3
4
5
6
7
8
9
10
11
12
# 14.beginOfMonth
获取某月的开始时间
@Test
public void test16() {
  String dateStr2 = "2021-05-16 22:50:34.111";
  DateTime date2 = DateUtil.parse(dateStr2, "yyyy-MM-dd HH:mm:ss.SSS");
  DateTime dateTime = DateUtil.beginOfMonth(date2);
  Assert.assertEquals("2021-05-01 00:00:00", dateTime.toString());
}
2
3
4
5
6
7
# 15.endOfMonth
获取某月的结束时间
@Test
public void test17() {
  String dateStr2 = "2021-05-16 22:50:34.111";
  DateTime date2 = DateUtil.parse(dateStr2, "yyyy-MM-dd HH:mm:ss.SSS");
  DateTime dateTime = DateUtil.endOfMonth(date2);
  Assert.assertEquals("2021-05-31 23:59:59", dateTime.toString());
}
2
3
4
5
6
7
# 16.beginOfQuarter
获取某季度的开始时间
 @Test
    public void test18() {
        DateTime dateTime = new DateTime("2021-05-16 23:34:23", DatePattern.NORM_DATETIME_FORMAT);
        // 精确到毫秒
        DateTime beginTime = new DateTime("2021-04-01 00:00:00.000", DatePattern.NORM_DATETIME_MS_FORMAT);
        dateTime = DateUtil.beginOfQuarter(dateTime);
        Assert.assertEquals(beginTime, dateTime);
    }
2
3
4
5
6
7
8
# 17.endOfQuarter
获取某季度的结束时间
@Test
    public void test19() {
        Date date = DateUtil.endOfQuarter(
                DateUtil.parse("2020-05-31 00:00:00"));
        Assert.assertEquals("2020-06-30 23:59:59", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
    }
2
3
4
5
6
# 18.beginOfYear
获取某年的开始时间
@Test
public void test20() {
    DateTime date = DateUtil.date();
    date.setField(DateField.YEAR, 2019);
    DateTime endOfYear = DateUtil.beginOfYear(date);
    Assert.assertEquals("2019-01-01 00:00:00", endOfYear.toString());
}
2
3
4
5
6
7
# 19.endOfYear
获取某年的结束时间
@Test
public void test21() {
    DateTime date = DateUtil.date();
    date.setField(DateField.YEAR, 2019);
    DateTime endOfYear = DateUtil.endOfYear(date);
    Assert.assertEquals("2019-12-31 23:59:59", endOfYear.toString());
}
2
3
4
5
6
7
# 20.yesterday
昨天
@Test
public void test22() {
    //昨天
    DateTime dateTime = DateUtil.yesterday();
    System.out.println(dateTime);
    Assert.assertNotNull(dateTime);
}
2
3
4
5
6
7
# 21.tomorrow
明天这个时间点
@Test
public void test23() {
    //明天
    DateTime dateTime = DateUtil.tomorrow();
    System.out.println(dateTime);
    Assert.assertNotNull(dateTime);
}
2
3
4
5
6
7
# 22.lastWeek
上周这个时间点
@Test
public void test24() {
    //上周
    DateTime dateTime = DateUtil.lastWeek();
    System.out.println(dateTime);
    Assert.assertNotNull(dateTime);
}
2
3
4
5
6
7
# 23.nextWeek
下周这个时间点
@Test
public void test25() {
  //下周
  DateTime dateTime = DateUtil.nextWeek();
  System.out.println(dateTime);
  Assert.assertNotNull(dateTime);
}
2
3
4
5
6
7
# 24.lastMonth
上个月
@Test
public void test26() {
    //上个月
    DateTime dateTime = DateUtil.lastMonth();
    System.out.println(dateTime);
    Assert.assertNotNull(dateTime);
}
2
3
4
5
6
7
# 25.nextMonth
下个月
@Test
public void test27() {
  //下个月
  DateTime dateTime = DateUtil.nextMonth();
  System.out.println(dateTime);
  Assert.assertNotNull(dateTime);
}
2
3
4
5
6
7
# 26.offsetMillisecond
偏移毫秒数
@Test
public void test28() {
  //偏移毫秒数
  String dateStr2 = "2021-05-16 22:50:34.111";
  DateTime date2 = DateUtil.parse(dateStr2);
  DateTime dateTime = DateUtil.offsetMillisecond(date2, 1);
  int millisecond = DateUtil.millisecond(dateTime);
  Assert.assertEquals(112, millisecond);
  dateTime = DateUtil.offsetMillisecond(date2, -1);
  millisecond = DateUtil.millisecond(dateTime);
  Assert.assertEquals(110, millisecond);
}
2
3
4
5
6
7
8
9
10
11
12
# 27.offsetSecond
偏移秒数
@Test
public void test29() {
  //偏移秒数
  String dateStr2 = "2021-05-16 22:50:34.111";
  DateTime date2 = DateUtil.parse(dateStr2);
  DateTime dateTime = DateUtil.offsetSecond(date2, 1);
  int second = DateUtil.second(dateTime);
  Assert.assertEquals(35, second);
  dateTime = DateUtil.offsetSecond(date2, -1);
  second = DateUtil.second(dateTime);
  Assert.assertEquals(33, second);
}
2
3
4
5
6
7
8
9
10
11
12
# 28.offsetMinute
偏移分钟
@Test
public void test30() {
  //偏移分钟
  String dateStr2 = "2021-05-16 22:50:34.111";
  DateTime date2 = DateUtil.parse(dateStr2);
  DateTime dateTime = DateUtil.offsetMinute(date2, 1);
  int minute = DateUtil.minute(dateTime);
  Assert.assertEquals(51, minute);
  dateTime = DateUtil.offsetMinute(date2, -1);
  minute = DateUtil.minute(dateTime);
  Assert.assertEquals(49, minute);
}
2
3
4
5
6
7
8
9
10
11
12
# 29.offsetHour
偏移小时
@Test
public void test31() {
  //偏移分钟
  String dateStr2 = "2021-05-16 22:50:34.111";
  DateTime date2 = DateUtil.parse(dateStr2);
  DateTime dateTime = DateUtil.offsetHour(date2, 1);
  int hour = DateUtil.hour(dateTime, true);
  Assert.assertEquals(23, hour);
  dateTime = DateUtil.offsetHour(date2, -1);
  hour = DateUtil.hour(dateTime, true);
  Assert.assertEquals(21, hour);
}
2
3
4
5
6
7
8
9
10
11
12
# 30.offsetDay
偏移天
@Test
public void test32() {
    //偏移天
    String dateStr2 = "2021-05-16 22:50:34";
    DateTime date2 = DateUtil.parse(dateStr2);
    DateTime dateTime = DateUtil.offsetDay(date2, 1);
    Assert.assertEquals("2021-05-17 22:50:34", dateTime.toString());
    dateTime = DateUtil.offsetDay(date2, -1);
    Assert.assertEquals("2021-05-15 22:50:34", dateTime.toString());
}
2
3
4
5
6
7
8
9
10
# 31.offsetWeek
偏移周
@Test
public void test33() {
  //偏移周
  String dateStr2 = "2021-05-16 22:50:34";
  DateTime date2 = DateUtil.parse(dateStr2);
  DateTime dateTime = DateUtil.offsetWeek(date2,1);
  Assert.assertEquals("2021-05-23 22:50:34", dateTime.toString());
  dateTime = DateUtil.offsetWeek(date2,-1);
  Assert.assertEquals("2021-05-09 22:50:34", dateTime.toString());
}
2
3
4
5
6
7
8
9
10
# 32.offsetMonth
偏移月
@Test
public void test34() {
  //偏移月
  String dateStr2 = "2021-05-16 22:50:34";
  DateTime date2 = DateUtil.parse(dateStr2);
  DateTime dateTime = DateUtil.offsetMonth(date2, 1);
  Assert.assertEquals("2021-06-16 22:50:34", dateTime.toString());
  dateTime = DateUtil.offsetMonth(date2, -1);
  Assert.assertEquals("2021-04-16 22:50:34", dateTime.toString());
}
2
3
4
5
6
7
8
9
10
# 33.offset
获取指定日期偏移指定时间后的时间,生成的偏移日期不影响原日期
@Test
public void test35() {
  String dateStr = "2017-03-01 22:33:23";
  Date date = DateUtil.parse(dateStr);
  Date newDate = DateUtil.offset(date, DateField.DAY_OF_MONTH, 2);
  Assert.assertEquals("2017-03-03 22:33:23", newDate.toString());
}
2
3
4
5
6
7
8
# 三.实战案例
# 1.获取前七天
- 使用 DateUtil 工具类进行加减
- 可以直接获取昨天的日期
- 昨天以及昨天之前的 7 天的日期
public static void main(String[] args) {
    List<String> dates = new ArrayList<>();
    final DateTime yesterdayDate = DateUtil.yesterday();
    final String yesterday = DateUtil.formatDate(yesterdayDate);
    dates.add(yesterday);
    for (int i = 1; i < 7; i++) {
        final DateTime dateTime = DateUtil.offsetDay(yesterdayDate, -i);
        dates.add(DateUtil.formatDate(dateTime));
    }
    for (String date : dates) {
        System.out.println(date);
    }
}
2
3
4
5
6
7
8
9
10
11
12
13
# 2.时间段
- 用到了 DateUtil 工具包
- 可以获取天的开始年月日时分秒
- 可以在这个时间的基础上进行加减
@Override
public List<CsdnRedPackage> updateFor4Days() {
    QueryWrapper<CsdnRedPackage> wrapper = new QueryWrapper<>();
    wrapper.eq("is_delete", 0);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    DateTime startOfDay = DateUtil.beginOfDay(DateUtil.date());
    String endFormattedDate = sdf.format(startOfDay);
    wrapper.le("create_time", endFormattedDate);
    final Date dateTime = DateUtil.offsetDay(startOfDay, -3);
    String startFormattedDate = sdf.format(dateTime);
    wrapper.ge("create_time", startFormattedDate);
    return this.list(wrapper);
}
2
3
4
5
6
7
8
9
10
11
12
13
# 3.日期最小值
最小值是加入一个比较器,然后 get 获取比较后的值
final Date min = content.stream().min(Comparator.comparing(x -> x.getTripletDate())).get().getTripletDate();
// 创建SimpleDateFormat对象,指定日期格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
// 使用format方法将Date对象转换为字符串
String minStr = dateFormat.format(min);
2
3
4
5
# 4.日期最大值
最大值是加入一个比较器,然后 get 获取比较后的值
final Date max = content.stream().max(Comparator.comparing(x -> x.getTripletDate())).get().getTripletDate();
// 创建SimpleDateFormat对象,指定日期格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
// 使用format方法将Date对象转换为字符串
String maxStr = dateFormat.format(max);
2
3
4
5
# 5.日期范围查询
- 已知开始日期和结束日期,使用 mybatis-plus 查询范围数据
- 获取指定格式的日期数据,不然查询会有差异
final Date startDate = query.getStartDate();
final Date endDate = query.getEndDate();
QueryWrapper<CsdnTripletDayInfo> wrapper = new QueryWrapper<>();
wrapper.eq("is_delete", 0);
if (Objects.nonNull(startDate)) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String startFormattedDate = sdf.format(startDate);
    wrapper.ge("triplet_date", startFormattedDate);
}
if (Objects.nonNull(endDate)) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String endFormattedDate = sdf.format(endDate);
    wrapper.le("triplet_date", endFormattedDate);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 6.每一天概览
- 已知最小日期和最大日期,求每一天的总金额,总个数,丢单个数
- 注意日期格式化
- 注意带条件的求和 sum
- 注意特殊字符的转义
<select id="dayRedPackage" resultType="com.kwan.springbootkwan.entity.dto.CsdnDayRedPackageDTO">
    SELECT DATE_FORMAT(create_time, '%Y-%m-%d')               AS redPackageDate
         , SUM(my_amount)                                     AS myAmount
         , COUNT(1)                                           AS redPackageCount
         , SUM(if(msg = 'completed' AND my_amount = 0, 1, 0)) AS loseRedPackageCount
    FROM csdn_red_package
    WHERE 1 = 1
      AND DATE_FORMAT(create_time
              , '%Y-%m-%d') <![CDATA[>= #{min}]]>
      AND DATE_FORMAT(create_time
              , '%Y-%m-%d') <![CDATA[<= #{max}
    ]]>
    GROUP BY redPackageDate
    ORDER BY redPackageDate
</select>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 7.最后一个的累计
<select id="theoryMaxAmount" resultType="java.lang.String">
    SELECT SUM(t2.received_money) AS received_money
    FROM (
             SELECT t.order_no AS order_no, MAX(t.receive_time) AS max_order_no_receive_time
             FROM (SELECT * FROM csdn_red_package_detail_info WHERE DATE (receive_time) = #{date}) t
    GROUP BY order_no) t1
        LEFT JOIN csdn_red_package_detail_info t2
    ON t1.order_no = t2.order_no AND t1.max_order_no_receive_time = t2.receive_time
</select>
2
3
4
5
6
7
8
9
# 8.获取天所在周月
public static void main(String[] args) {
        // 获取当前日期时间
        DateTime now = DateUtil.date();
        // 获取当前日期所在的周数
        int weekOfYear = DateUtil.weekOfYear(now);
        // 获取当前日期所在的月份,并格式化为两位数字
        String month = String.format("%02d", DateUtil.month(now) + 1);
        // 将周数和月份拼接成字符串
        String result = StrUtil.format("当前日期所在的周数:{},当前日期所在的月份:{}", weekOfYear, month);
        System.out.println(result);
    }
2
3
4
5
6
7
8
9
10
11
# 9.找到最近一天
final Optional<CityAndRegionAndCountryBrandSkuRepDTO> max = orrSkus.stream().filter(t ->
                                StringUtils.isNotEmpty(t.getPeriod_sdate()) && StringUtils.isNotEmpty(skuRep.getPeriod_sdate()) &&              DateTimeUtils.dateDiff(DateTimeUtils.str2Date(t.getPeriod_sdate()), DateTimeUtils.str2Date(skuRep.getPeriod_sdate())) > 0)                  .max(Comparator.comparing(CityAndRegionAndCountryBrandSkuRepDTO::getPeriod_sdate));
                        if (max.isPresent()) {
                            final CityAndRegionAndCountryBrandSkuRepDTO periodSdateOrr = max.get();}
2
3
4
# 10.每一天的 top30
你这个问题有点不明确,不知道是什么数据需要排名,下面我以网站访问量为例,给出一种计算每天 top30 访问量的方法。
假设你有一个这样的数据文件,每一行表示某一天某个网站的访问量:
2022-01-01,website1,100
2022-01-01,website2,200
2022-01-01,website3,300
2022-01-02,website1,150
2022-01-02,website2,250
2022-01-02,website3,350
2022-01-03,website1,180
2022-01-03,website2,280
2022-01-03,website3,380
2
3
4
5
6
7
8
9
你可以按照日期进行分组,然后对每一组的数据按照访问量排序,取前 30 就是每一天的 top30 访问量。下面是一段 Java 代码实现这个逻辑:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Top30ByDay {
    public static class Record {
        private Date date;
        private String website;
        private int visits;
        public Record(Date date, String website, int visits) {
            this.date = date;
            this.website = website;
            this.visits = visits;
        }
        public Date getDate() {
            return date;
        }
        public String getWebsite() {
            return website;
        }
        public int getVisits() {
            return visits;
        }
    }
    public static void main(String[] args) throws IOException {
        // 读取数据文件
        List<Record> records = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] fields = line.split(",");
                Date date = new SimpleDateFormat("yyyy-MM-dd").parse(fields[0]);
                String website = fields[1];
                int visits = Integer.parseInt(fields[2]);
                Record record = new Record(date, website, visits);
                records.add(record);
            }
        }
        // 按照日期分组,计算每一天的top30访问量
        Map<Date, List<Record>> groupByDate = records.stream()
                .collect(Collectors.groupingBy(Record::getDate));
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        for (Map.Entry<Date, List<Record>> entry : groupByDate.entrySet()) {
            Date date = entry.getKey();
            List<Record> recordsByDay = entry.getValue();
            List<Record> top30ByDay = recordsByDay.stream()
                    .sorted(Comparator.comparingInt(Record::getVisits).reversed())
                    .limit(30)
                    .collect(Collectors.toList());
            System.out.println(dateFormat.format(date) + " top 30:");
            for (Record record : top30ByDay) {
                System.out.println(record.getWebsite() + " " + record.getVisits());
            }
            System.out.println();
        }
    }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
这个代码使用 Java 8 的 Stream API,将数据按照日期分组,然后对每一组的数据按照访问量排序并取前 30,输出每一天的 top30 访问量。在这个例子中,我使用了 Java 的日期处理库java.util.Date和java.text.SimpleDateFormat,你可以根据自己的需求替换成其他日期处理库。
