JDK8日期时间类型LocalDateTime、LocalDate、LocalTime的使用例子

8 篇文章 0 订阅

JDK8推出了很多新特性,比如:


这篇文章总结了一下stream()流式计算的使用例子。


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


最近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); //倒序修改为顺序
   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) throws ParseException {

        //输入:2020-07,输出:2020-07-01、2020-07-02、2020-07-03……2020-07-31;
        String dateStr = "2020-07";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        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);

        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        while (month == cal.get(Calendar.MONTH)) {
            System.out.println(sdf1.format(cal.getTime()));
            cal.add(Calendar.DAY_OF_MONTH, 1);
        }

    }

运行输出:

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();


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值