# 一.基本介绍
# 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
,你可以根据自己的需求替换成其他日期处理库。