JDK8推出了很多新特性,比如:
- 函数式接口
- Lambda表达式
- Stream API流式计算 参考: JDK8语法糖stream()流式计算的使用例子
- 接口中的默认方法与静态方法
- 方法引用与构造器引用
- 新日期API
这篇文章总结了一下stream()流式计算的使用例子。
文章目录
- 常用类
- 常用示例
- 获取当前日期时间、指定日期时间
- LocalDateTime转Date、Date转LocalDateTime
- Date转LocalDate
- LocalDateTime转String、String转LocalDateTime
- LocalDate转String、String转LocalDate
- LocalTime转String、String转LocalTime
- LocalDateTime转LocalDate、LocalTime
- ISO DateTime转LocalDateTime、LocalDateTime转 ISO DateTime
- 不规范的时间、日期格式的转换
- 获取时间戳
- 两个日期相差天数
- 根据生日日期获取年龄
- 计算日期的时间差,计算相差天数、小时数、分钟数、秒数、毫秒数
- 平年、闰年
- @RequestBody+@JsonFormat接收日期时间格式
- 时间加减、日期加减操作
- 最近7天的每一天的日期
- 获取指定日期的开始时间00:00:00、结束时间23:59:59
- 获取本周第一天、本周最后一天、本周每一天
- 获取本月第一天、本月任意一天
- 获取本年第一个月、本年任意一个月
- 示例:获取本日、本周、本月、本年到今天的开始和结束时间
- 获取指定日期(LocalDate)当月的第一天
- 获取指定日期(LocalDate)当月的最后一天
- 获取指定月份的总天数
- 获取指定月份的每一天
- 获取日期集合里最小日期、最大日期
JDK8以前日期时间类型统一使用的是java.util.Date,JDK8以后在java.time包下定义了三种新的日期时间类型LocalDateTime、LocalDate、LocalTime。
最近项目中使用日期类型比较多,这里做下总结。
常用类
类型 | 用途 |
---|---|
LocalDateTime | 用于“年月日时分秒”的类型,比如:yyyy-MM-dd HH:mm:ss |
LocalDate | 用于“年月日”的类型,比如yyyy-MM-dd |
LocalTime | 用于“时分秒”的类型,比如:HH:mm:ss |
DateTimeFormatter | 用于时间日期格式化 |
ZoneOffset.of(“+8”) | 表示东八区,即北京时间 |
ChronoUnit | 时间单位常量类,日期时间加减时使用 |
常用示例
获取当前日期时间、指定日期时间
//获取当前日期时间
LocalDateTime localDateTime = LocalDateTime.now(); // 2020-08-04 16:43:02
//获取当前日期
LocalDate localDate = LocalDate.now(); // 2020-08-04
//获取当前时间
LocalTime localTime = LocalTime.now(); // 16:43:02
//获取指定日期时间
LocalDateTime localDateTime2 = LocalDateTime.of(2020, 1, 1, 23, 59, 59); // 2020-01-01 23:59:59
//获取指定日期
LocalDate localDate2 = LocalDate.of(2020, 1, 1); // 2020-01-01
//获取指定时间
LocalTime localTime2 = LocalTime.of(23, 59, 59); // 23:59:59
LocalTime localTime3 = LocalTime.of(23, 59); // 23:59:00
LocalTime localTime4 = LocalTime.parse("23:59:59"); // 23:59:00
LocalTime localTime5 = LocalTime.parse("23:59:59", DateTimeFormatter.ofPattern("HH:mm:ss"));// 23:59:00
LocalDateTime转Date、Date转LocalDateTime
//获取当前日期时间
LocalDateTime localDateTime = LocalDateTime.now();
// LocalDateTime转Date
Date date = Date.from(localDateTime.toInstant(ZoneOffset.of("+8")));
// Date转LocalDateTime,方式一
LocalDateTime localDateTime1 = LocalDateTime.ofInstant(date.toInstant(), ZoneOffset.of("+8"));
// Date转LocalDateTime,方式二
LocalDateTime localDateTime2 = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
运行结果:(相互转换后的日期时间是相等的)
Date转LocalDate
Date date = new Date();
// Date 转 LocalDate
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDateTime转String、String转LocalDateTime
// 格式化
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// LocalDateTime转String,方式一
String dateTimeStr = LocalDateTime.now(ZoneOffset.of("+8")).format(dtf);
System.out.println(dateTimeStr); // 2020-08-03 20:42:55
// LocalDateTime转String,方式二
dateTimeStr = dtf.format(LocalDateTime.now());
System.out.println(dateTimeStr); // 2020-08-03 20:42:55
// String转LocalDateTime
LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, dtf);
System.out.println(dateTimeStr);
运行结果:
2020-08-03 20:55:55
2020-08-03 20:55:55
2020-08-03 20:55:55
LocalDate转String、String转LocalDate
// 格式化
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// String转LocalDate
LocalDate localDate = LocalDate.parse("20200803", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate localDate2 = LocalDate.parse("2020-08-03", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(localDate); // 2020-08-03
System.out.println(localDate2); // 2020-08-03
// LocalDate转String
String localDateStr = dtf.format(LocalDate.now())
System.out.println(localDateStr); // 2020-08-03
// LocalDate转String
LocalDate localDate = LocalDate.parse("2020-09-04");
String yearMonth = DateTimeFormatter.ofPattern("yyyy-MM").format(localDate);
String monthDay = DateTimeFormatter.ofPattern("MM-dd").format(localDate);
System.out.println(yearMonth); // 2020-09
System.out.println(monthDay); // 09-04
运行结果:
2020-08-03
2020-08-03
2020-08-03
2020-09
09-04
LocalTime转String、String转LocalTime
LocalTime localTime = LocalTime.of(8, 30, 0);
// LocalTime转String
String localTimeStr = DateTimeFormatter.ofPattern("HH:mm:ss").format(localTime);
System.out.println(localTimeStr); //08:30:00
// String转LocalTime
LocalTime localTime2 = LocalTime.parse(localTimeStr, DateTimeFormatter.ofPattern("HH:mm:ss"));
LocalDateTime转LocalDate、LocalTime
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
ISO DateTime转LocalDateTime、LocalDateTime转 ISO DateTime
利用jdk的工具类OffsetDateTime转换
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
String isoDateTimeStr = "2016-10-15T00:00:01.000+08:00";
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
OffsetDateTime offsetDateTime = OffsetDateTime.parse(isoDateTimeStr, formatter);
LocalDateTime localDateTime = offsetDateTime.toLocalDateTime(); //LocalDateTime值为 2016-10-15 00:00:01
不知道有这个工具类,也可以用蠢办法:
import cn.hutool.core.date.DateUtil;
String isoDateTimeStr = "2016-10-15T00:00:01.000+08:00";
//截取yyyy-MM-dd HH:mm:ss字符串,并替换掉T
isoDateTimeStr.substring(0, 19).replace("T", " ");
LocalDateTime localDateTime = DateUtil.parseLocalDateTime(substring); //LocalDateTime值为 2016-10-15 00:00:01
//LocalDateTime转 ISO DateTime
String format = DateUtil.format(localDateTime, "yyyy-MM-dd'T'HH:mm:ss");
LocalDateTime isoDateTimeStr2 = format.concat("+08:00"); //字符串值为 2016-10-15T00:00:01.000+08:00
不规范的时间、日期格式的转换
通常的时间格式是"yyyy-MM-dd HH:mm:ss",以上的转换方式LocalDateTime.parse()、LocalDate.parse()、LocalTime.parse()没问题。如2020-08-30 01:00:22,但如果是2020/08/30 00:00:01或者2020-8-30 1:00:22,这时用LocalDateTime.parse()、LocalDate.parse()、LocalTime.parse()就会报错。那怎么办呢?
传统的SimpleDateFormat兼容性更强,解决方案:先SimpleDateFormat转Date,再Date转LocalDateTime。
String dateStr = "2020/08/30 00:00:01";
dateStr = dateStr.replaceAll("\\/", "-");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(dateStr);
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
总之,如果用jdk8新特性对不规范的时间、日期格式转换不好用时,就用传统的Date、SimpleDateFormat过渡一下。
获取时间戳
LocalDateTime获取时间戳,精确到毫秒数、精确到秒数。
// 精确到毫秒数
Date date = new Date(); //Date
Instant instant = date.toInstant(); //Date -> Instant
Date date1 = Date.from(instant); //Instant -> Date
LocalDateTime localDateTime = LocalDateTime.now(); //LocalDateTime
System.out.println(date.getTime());
System.out.println(instant.toEpochMilli());
System.out.println(date1.getTime());
System.out.println(localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli());
// 精确到秒数
System.out.println(localDateTime.toEpochSecond(ZoneOffset.of("+8")));
System.out.println(instant.getEpochSecond());
控制台输出:
1714284877210
1714284877210
1714284877210
1714284877278
1714284877
1714284877
LocalDate获取时间戳,精确到毫秒数。
LocalDate.now().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
两个日期相差天数
// 两个日期相差天数,方式一
LocalDate day1 = LocalDate.of(2020, 1, 1); // 2020-01-01
LocalDate day2 = LocalDate.of(2020, 2, 1); // 2020-02-01
long l = day2.toEpochDay() - day1.toEpochDay(); // 31
// 两个日期相差天数,方式二
LocalDate day1 = LocalDate.of(2020, 1, 1); // 2020-01-01
LocalDate day2 = day1.plus(10, ChronoUnit.DAYS); // 加10天,2020-01-10
Period period = Period.between(day1, day2);
System.out.println("相差多少天:" + period.getDays() + ",相差几个月=" + period.getMonths() + ",相差几年=" + period.getYears());
// 日期equals比较
LocalDate day1 = LocalDate.of(2020, 1, 1); // 2020-01-01
LocalDate day2 = LocalDate.of(2020, 1, 1); // 2020-02-01
boolean flag = day1.equals(day2); // true
根据生日日期获取年龄
根据生日当天为分界线来计算年龄。
private static int getAgeByBirthday(LocalDate birthday) {
int age = 0;
try {
Calendar now = Calendar.getInstance();
now.setTime(new Date());// 当前时间
now.setTimeInMillis(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
Calendar birth = Calendar.getInstance();
birth.setTimeInMillis(birthday.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli());
if (birth.after(now)) {// 如果传入的时间,在当前时间的后面,返回0岁
age = 0;
} else {
age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR) - 1;
if (now.get(Calendar.MONTH) >= birth.get(Calendar.MONTH)) {
if (now.get(Calendar.DAY_OF_MONTH) >= birth.get(Calendar.DAY_OF_MONTH)) {
age += 1;
}
}
}
return age;
} catch (Exception e) {
return 0;
}
}
计算日期的时间差,计算相差天数、小时数、分钟数、秒数、毫秒数
LocalTime、LocalDate和LocalDateTime都可以借助java.time.Duration的between()方法计算时间差,
- getSeconds() 获取相差秒数
- toMillis() 获取相差毫秒数
- toNanos() 获取相差纳秒数
- toMinutes() 获取相差分钟数
- toHours() 获取相差小时数
- toDays() 获取相差天数
LocalTime startTime = LocalTime.of(9, 0, 0); // 09:00:00
LocalTime endTime = LocalTime.of(9, 1, 0); // 18:01:00
Duration.between(startTime, endTime).getSeconds(); //获取相差秒数,返回60
Duration.between(endTime, startTime).getSeconds(); //获取相差秒数,返回-60
平年、闰年
LocalDate today = LocalDate.now();
if (today.isLeapYear()) {
System.out.println(today.getYear() + "是闰年");
} else {
System.out.println(today.getYear() + "是平年");
}
运行结果:
2020是闰年
闰年的计算公式:四年一闰,百年不闰,四百年再闰
public boolean isLeapYear(long prolepticYear) {
return ((prolepticYear & 3) == 0) && ((prolepticYear % 100) != 0 || (prolepticYear % 400) == 0);
}
@RequestBody+@JsonFormat接收日期时间格式
在Controller类里,方法使用“@RequestParam LocalDate date,@RequestParam LocalDateTime dateTime” 接收日期时间参数可以使用配置类自动转换,但配置类对@RequestBody 对象包含的日期时间参数不起作用。我的解决办法是:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime attendanceTime;
在属性上面加@JsonFormat注解,指定日期时间格式化。
我的 配置类:
/**
* 日期时间类型转换器配置
*
* @Author wanglingqiang
* @Date 2020/7/9 下午12:28
**/
@Configuration
public class DateConfig {
/**
* LocalDate转换器,用于转换RequestParam和PathVariable参数
*/
@Bean
public Converter<String, LocalDate> localDateConverter() {
return new Converter<String, LocalDate>() {
@Override
public LocalDate convert(@NotNull String source) {
return LocalDate.parse(source, DateTimeFormatter.ofPattern(Constants.DEFAULT_DATE_FORMAT));
}
};
}
/**
* LocalDateTime转换器,用于转换RequestParam和PathVariable参数
*/
@Bean
public Converter<String, LocalDateTime> localDateTimeConverter() {
return new Converter<String, LocalDateTime>() {
@Override
public LocalDateTime convert(@NotNull String source) {
return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(Constants.DEFAULT_DATE_TIME_FORMAT));
}
};
}
/**
* LocalTime转换器,用于转换RequestParam和PathVariable参数
*/
@Bean
public Converter<String, LocalTime> localTimeConverter() {
return new Converter<String, LocalTime>() {
@Override
public LocalTime convert(@NotNull String source) {
return LocalTime.parse(source, DateTimeFormatter.ofPattern(Constants.DEFAULT_TIME_FORMAT));
}
};
}
/**
* Date转换器,用于转换RequestParam和PathVariable参数
*/
@Bean
public Converter<String, Date> dateConverter() {
return new Converter<String, Date>() {
@Override
public Date convert(@NotNull String source) {
SimpleDateFormat format = new SimpleDateFormat(Constants.DEFAULT_DATE_TIME_FORMAT);
try {
return format.parse(source);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
};
}
/**
* Json序列化和反序列化转换器,用于转换Post请求体中的json以及将我们的对象序列化为返回响应的json
*/
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
//LocalDateTime系列序列化和反序列化模块,继承自jsr310,我们在这里修改了日期格式
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(Constants.DEFAULT_DATE_TIME_FORMAT)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(Constants.DEFAULT_DATE_FORMAT)));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(Constants.DEFAULT_TIME_FORMAT)));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(Constants.DEFAULT_DATE_TIME_FORMAT)));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(Constants.DEFAULT_DATE_FORMAT)));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(Constants.DEFAULT_TIME_FORMAT)));
//Date序列化和反序列化
javaTimeModule.addSerializer(Date.class, new JsonSerializer<Date>() {
@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
SimpleDateFormat formatter = new SimpleDateFormat(Constants.DEFAULT_DATE_TIME_FORMAT);
String formattedDate = formatter.format(date);
jsonGenerator.writeString(formattedDate);
}
});
javaTimeModule.addDeserializer(Date.class, new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
SimpleDateFormat format = new SimpleDateFormat(Constants.DEFAULT_DATE_TIME_FORMAT);
String date = jsonParser.getText();
try {
return format.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
});
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}
实际使用时,发现对@RequestBody 对象包含的日期时间参数不起作用,有知道的请留言指教。
时间加减、日期加减操作
LocalTime、LocalDate和LocalDateTime都提供有plus()、minus()做加减操作。
时间加减操作:
LocalTime time1 = LocalTime.of(9, 0, 0); // 09:00:00
LocalTime time2 = LocalTime.of(18, 0, 0); // 18:00:00
LocalTime startTime = time1.plusMinutes(30); // 加30分钟,09:30:00
LocalTime endTime = time2.minusMinutes(30); // 减30分钟,17:30:00
日期加减操作:
LocalDate today = LocalDate.now();
System.out.println("today=" + today);
// 一个星期后
LocalDate nextweek = today.plus(1, ChronoUnit.WEEKS);
// LocalDate nextweek = today.plus(7,ChronoUnit.DAYS);
System.out.println("nextweek=" + nextweek);
// 一个月前,或者today.minus(1, ChronoUnit.MONTHS)
LocalDate lastMonth = today.minusMonths(1L);
System.out.println("lastMonth =" + lastMonth );
// 一个月后
LocalDate nextMonth = today.plus(1, ChronoUnit.MONTHS);
System.out.println("nextMonth=" + nextMonth);
// 一年后日期
LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);
System.out.println("nextYear=" + nextYear);
// 10年后日期
LocalDate nextTenyear = today.plus(1, ChronoUnit.DECADES);
System.out.println("Date after ten year:" + nextTenyear);
运行结果:
today=2020-08-04
nextweek=2020-08-11
lastMonth=2020-07-04
nextMonth=2020-09-04
nextYear=2021-08-04
Date after ten year:2030-08-04
java.util.Date日期类型的加减操作:
//今天
Date date = new Date();
//7天前的日期,即今天-6
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, -6);
Date date2 = cal.getTime();
最近7天的每一天的日期
days是7,可以获取最近7天的每一天的日期;days是15,可以获取最近半个月的每一天的日期;days是30,可以获取最近一个月的每一天的日期。以此类推。
public static void main(String[] args) {
int days = 7;
List<LocalDate> recentDates = getRecentDates(days);
System.out.println(recentDates);
}
private static List<LocalDate> getRecentDates(int days) {
List<LocalDate> recentDates = Lists.newArrayList();
LocalDate localDate = LocalDate.now();
recentDates.add(localDate);
for (int i = 1; i < days; i++) {
localDate = localDate.minus(1, ChronoUnit.DAYS);
recentDates.add(localDate);
}
Collections.sort(recentDates); //顺序
//Collections.sort(recentDates, (o1, o2) -> o2.compareTo(o1)); //倒序 方式一
//Collections.sort(recentDates, Comparator.reverseOrder()); //倒序 方式二
return recentDates;
}
private static List<Date> getRecentDates2(int days) {
List<Date> recentDates = new ArrayList<>();
Calendar cal = Calendar.getInstance();
recentDates.add(cal.getTime());
for (int i = 1; i < days; i++) {
cal.add(Calendar.DAY_OF_MONTH, -1);
recentDates.add(cal.getTime());
}
//Collections.sort(recentDates, (o1, o2) -> o2.compareTo(o1)); //倒序 方式一
Collections.sort(recentDates, Comparator.reverseOrder()); //倒序 方式二
return recentDates;
}
今天是2020-09-04,输入结果是:
[2020-08-29, 2020-08-30, 2020-08-31, 2020-09-01, 2020-09-02, 2020-09-03, 2020-09-04]
获取指定日期的开始时间00:00:00、结束时间23:59:59
比如今天是2020-08-04,可以使用LocalDateTime.of()方法,返回2020-08-04 00:00:00、2020-08-04 23:59:59。
LocalDate localDate = LocalDate.now();
LocalDateTime startDateTime = LocalDateTime.of(localDate, LocalTime.MIN);
LocalDateTime endDateTime = LocalDateTime.of(localDate, LocalTime.MAX);
// 格式化
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dtf.format(startDateTime));
System.out.println(dtf.format(endDateTime));
运行结果:
2020-08-04 00:00:00
2020-08-04 23:59:59
获取本周第一天、本周最后一天、本周每一天
LocalDate now = LocalDate.now();
LocalDate firstDayOfWeek = now.with(DayOfWeek.MONDAY); //本周的第一天,即周一
LocalDate lastDayOfWeek = now.with(DayOfWeek.SUNDAY); //本周的最后一天,即周日
//TODO 根据DayOfWeek枚举类可以获取本周任意一天
// 获取本周的所有日期
List<LocalDate> datesOfWeek = new ArrayList<>();
for (LocalDate date = firstDayOfWeek; !date.isAfter(lastDayOfWeek); date = date.plusDays(1)) {
datesOfWeek.add(date);
}
System.out.println("本周的所有日期: " + datesOfWeek);
获取本月第一天、本月任意一天
LocalDate firstDayOfMonth = now.withDayOfMonth(1); //本月第一天
// TODO 根据withDayOfMonth()的入参,可以获取本月任意一天
获取本年第一个月、本年任意一个月
LocalDate firstMonthOfYear = now.withMonth(1).withDayOfMonth(1); //获取本年第一个月,即当前年的1月1号
// TODO 根据withMonth()的入参,可以获取本年任意一个月
示例:获取本日、本周、本月、本年到今天的开始和结束时间
下面示例方法返回的是开始、结束时间的字符串,如果需要返回时间对象类型,去掉format()方法即可。
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 获取本日到今天的开始、结束时间
* 获取本周周一到今天的开始、结束时间
* 获取本月一号到今天的开始、结束时间
* 获取本年一月一号到今天的开始、结束时间
*
* @param type 1本日、2本周、3本月、4本年
* @return
*/
public static String[] getStartTimeAndEndTime(Integer type) {
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = localDateTime.toLocalDate();
String startTime, endTime = LocalDateTime.of(localDate, LocalTime.MAX).format(TIME_FORMATTER);
switch (type) {
case 1:
startTime = LocalDateTime.of(localDate, LocalTime.MIN).format(TIME_FORMATTER);
break;
case 2:
startTime = LocalDateTime.of(localDateTime.with(DayOfWeek.MONDAY).toLocalDate(), LocalTime.MIN).format(TIME_FORMATTER);
break;
case 3:
startTime = LocalDateTime.of(localDateTime.withDayOfMonth(1).toLocalDate(), LocalTime.MIN).format(TIME_FORMATTER);
break;
case 4:
startTime = LocalDateTime.of(localDateTime.withMonth(1).withDayOfMonth(1).toLocalDate(), LocalTime.MIN).format(TIME_FORMATTER);
break;
default:
throw new IllegalArgumentException("type参数异常");
}
return new String[]{startTime, endTime};
}
测试:
public static void main(String[] args) {
String[] timeArray = getStartTimeAndEndTime(1);
System.out.println("本日:" + timeArray[0] + "\t" + timeArray[1]);
timeArray = getStartTimeAndEndTime(2);
System.out.println("本周:" + timeArray[0] + "\t" + timeArray[1]);
timeArray = getStartTimeAndEndTime(3);
System.out.println("本月:" + timeArray[0] + "\t" + timeArray[1]);
timeArray = getStartTimeAndEndTime(4);
System.out.println("本年:" + timeArray[0] + "\t" + timeArray[1]);
}
输出结果:
本日:2023-10-12 00:00:00 2023-10-12 23:59:59
本周:2023-10-09 00:00:00 2023-10-12 23:59:59
本月:2023-10-01 00:00:00 2023-10-12 23:59:59
本年:2023-01-01 00:00:00 2023-10-12 23:59:59
获取指定日期(LocalDate)当月的第一天
方法一:
/**
* 获取当月的第一天
*
* @param
* @return String
**/
private String getFirstDayOfMonth() {
LocalDate today = LocalDate.now(); // 也可以指定不同的日期,获取指定月的第一天
return localDate.with(TemporalAdjusters.firstDayOfMonth());
}
方法二:
/**
* 获取当月的第一天
*
* @param
* @return String
**/
private String getFirstDayOfMonth() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Calendar cale = Calendar.getInstance();
cale.add(Calendar.MONTH, 0);
cale.set(Calendar.DAY_OF_MONTH, 1);
return format.format(cale.getTime());
}
运行输出:
2020-08-01
获取指定日期(LocalDate)当月的最后一天
方法一:
/**
* 获取当月的最后一天
*
* @param
* @return String
**/
private String getLastDayOfMonth() {
LocalDate today = LocalDate.now();// 也可以指定不同的日期,获取指定月的最后一天
return localDate.with(TemporalAdjusters.lastDayOfMonth());
}
方法二:
/**
* 获取当月的最后一天
*
* @param
* @return String
**/
private String getLastDayOfMonth() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Calendar cale = Calendar.getInstance();
cale.add(Calendar.MONTH, 1);
cale.set(Calendar.DAY_OF_MONTH, 0);
return format.format(cale.getTime());
}
运行输出:
2020-08-31
获取指定月份的总天数
比如:2月有29天、6月有30天、7月有31天。
方式一:
int days1 = LocalDate.of(2020, 2, 27).lengthOfMonth();
int days2 = LocalDate.of(2020, 6, 27).lengthOfMonth();
int days3 = LocalDate.of(2020, 7, 27).lengthOfMonth();
System.out.println(days1); //2020年2月,输出29天
System.out.println(days2); //2020年6月,输出30天
System.out.println(days3); //2020年7月,输出31天
运行结果:
29
30
31
方式二:
/**
* 获取指定月份的总天数
*
* @param dateStr 格式:yyyy-MM
* @return Integer
**/
private Integer getDaysOfMonth(String dateStr) {
try {
Date date = new SimpleDateFormat("yyyy-MM").parse(dateStr);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
} catch (ParseException e) {
log.error("", e);
return null;
}
}
传参:2020-08,运行结果:
31
获取指定月份的每一天
输入:2020-07
输出:2020-07-01、2020-07-02、2020-07-03……2020-07-31;
public static void main(String[] args) {
//输入:2020-07,输出:2020-07-01、2020-07-02、2020-07-03……2020-07-31;
getEverydayOfMonth("2020-07");
}
/**
* 获取指定月份的每一天
* @param dateStr 2020-07
* @return 2020-07-01、2020-07-02、2020-07-03……2020-07-31
*/
private static List<Date> getEverydayOfMonth(String dateStr) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
Calendar now = Calendar.getInstance();
List<Date> dateList = new ArrayList<>();
try {
Date date = sdf.parse(dateStr);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, 1);
int month = cal.get(Calendar.MONTH);
while (month == cal.get(Calendar.MONTH)) {
if (now.compareTo(cal) < 0) {
//大于今天,终止
break;
}
dateList.add(cal.getTime());
System.out.println(sdf1.format(cal.getTime()));
cal.add(Calendar.DAY_OF_MONTH, 1);
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
return dateList;
}
运行输出:
2020-07-01
2020-07-02
2020-07-03
2020-07-04// …中间省略
2020-07-29
2020-07-30
2020-07-31
获取日期集合里最小日期、最大日期
LocalDate today = LocalDate.now();
//日期集合
List<LocalDate> dateList = new ArrayList<>();
dateList.add(null);
dateList.add(today.minusDays(1));
dateList.add(today);
dateList.add(today.plusDays(2));
//这里过滤掉null值,不然下面compareTo()会报空值异常
Set<LocalDate> dateSet = dateList.stream().filter(e -> Objects.nonNull(e)).collect(Collectors.toSet());
//获取日期集合里最小日期
LocalDate minDate = dateSet.stream().min(LocalDate::compareTo).get();
//获取日期集合里最大日期
LocalDate maxDate = dateSet.stream().max(LocalDate::compareTo).get();