Java日期常用示例

日期格式化

java.util.date和java.time.LocalDateTime格式化

应用示例

1
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
/**
* 格式化日期
* @param date 待格式化的日期
* @param pattern 格式化正则
* @return 格式化结果串
*/
public static String format(Date date, String pattern){
return new SimpleDateFormat(pattern).format(date);
}

/**
* 格式化日期
* @param localDateTime 待格式化的日期
* @param pattern 格式化正式
* @return 格式化结果串
*/
public static String format(LocalDateTime localDateTime, String pattern){
return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
}

/**
* 格式化日期
* @param localDate 待格式化的日期
* @param pattern 格式化正则, 这里使用的类型 {@link LocalDate}, 所以正则只能设定到天
* @return 格式化结果串
*/
public static String format(LocalDate localDate, String pattern){
return localDate.format(DateTimeFormatter.ofPattern(pattern));
}

示例测试

1
2
3
4
5
6
// 2017-08-28 15:45:02
System.out.println(format(new Date(), "yyyy-MM-dd HH:mm:ss"));
// 2017-08-28 15:45:02
System.out.println(format((LocalDateTime.now()), "yyyy-MM-dd HH:mm:ss"));
// 2017-08-28
System.out.println(format((LocalDateTime.now().toLocalDate()), "yyyy-MM-dd"));

日期转换

java.util.date和java.time.LocalDateTime互相转换

应用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 将 {@link LocalDateTime} 转换成 {@link Date}
* @param localDateTime {@link LocalDateTime} 待转换的日期
* @return 转换成Date结果
*/
public static Date from(LocalDateTime localDateTime){
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
return Date.from(instant);
}

/**
* 将 {@link Date} 转换成 {@link LocalDateTime}
* @param date {@link Date} 待转换的日期
* @return 转换成 {@link LocalDateTime} 结果
*/
public static LocalDateTime from(Date date){
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}

示例测试

1
2
3
4
5
6
String patternTime = "yyyy-MM-dd HH:mm:ss";
Date now = new Date();
// 2017-08-28 14:47:10
System.out.println(format(from(now), patternTime));
// 2017-08-28 14:47:10
System.out.println(format(from(LocalDateTime.now()), patternTime));

区间集合

计算两端日期之间内的日期天数集合

示例代码

1
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
72
73
74
75
76
77
78
79
80
81
/**
* 获取{@link Date}在开始时间和结束时间内的日期时间段{@link Date}集合
* @param start 开始时间
* @param end 结束时间
* @return 时间天数集合
*/
public static List<Date> dateZones(Date start, Date end){
return dateZones(from(start), from(end));
}


/**
* 获取 {@link LocalDate} 在开始时间和结束时间内的日期时间段 {@link LocalDate} 集合
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List<Date> dateZones(LocalDate start, LocalDate end){
return Stream.iterate(start, x -> x.plusDays(1))
.limit(ChronoUnit.DAYS.between(start, end) + 1)
.map(e -> Date.from(e.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()))
.collect(Collectors.toList());
}


/**
* 获取{@link LocalDateTime} 在开始时间和结束时间内的日期时间段{@link Date}集合
* @param start 开始时间
* @param end 结束时间
* @return 时间天数集合
*/
public static List<Date> dateZones(LocalDateTime start, LocalDateTime end){
// 用起始时间作为流的源头,按照每次加一天的方式创建一个无限流
return Stream.iterate(start.toLocalDate(), x -> x.plusDays(1))
// 截断无限流,长度为起始时间和结束时间的差+1个
.limit(ChronoUnit.DAYS.between(start, end) + 1)
// 由于最后要的是字符串,所以map转换一下
.map(e -> Date.from(e.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()))
// 把流收集为List
.collect(Collectors.toList());
}


/**
* 获取{@link Date}在开始时间和结束时间内的日期时间段{@link LocalDate}集合
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List<LocalDate> localDateZones(Date start, Date end){
return localDateZones(from(start), from(end));
}


/**
* 获取 {@link LocalDate} 在开始时间和结束时间内的日期时间段 {@link LocalDate} 集合
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List<LocalDate> localDateZones(LocalDate start, LocalDate end){
return Stream.iterate(start, x -> x.plusDays(1))
.limit(ChronoUnit.DAYS.between(start, end) + 1)
.collect(Collectors.toList());
}

/**
* 获取 {@link LocalDateTime} 在开始时间和结束时间内的日期时间段 {@link LocalDate} 集合
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List<LocalDate> localDateZones(LocalDateTime start, LocalDateTime end){
// 用起始时间作为流的源头,按照每次加一天的方式创建一个无限流
return Stream.iterate(start.toLocalDate(), x -> x.plusDays(1))
// 截断无限流,长度为起始时间和结束时间的差+1个
.limit(ChronoUnit.DAYS.between(start, end) + 1)
.map(e -> e.atStartOfDay().toLocalDate())
// 把流收集为List
.collect(Collectors.toList());
}

示例测试

1
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
String patternDate = "yyyy-MM-dd";
List<Date> dateList = Arrays.asList(new Date(2017-1900, 11, 30), new Date(2018-1900, 0, 3));

// 2017-12-30
System.out.println("开始时间:" + format(dateList.get(0), patternDate) + ", 结束时间:" + format(dateList.get(1), patternDate));

// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(dateZones(dateList.get(0), dateList.get(1)).stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));
// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(localDateZones(dateList.get(0), dateList.get(1)).stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));


LocalDateTime now = LocalDateTime.of(2017, Month.DECEMBER, 30, 0, 0, 0);

// 2017-12-30
System.out.println(format(now, patternDate));

// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(dateZones(now, now.plus(4, ChronoUnit.DAYS))
.stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));

// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(localDateZones(now, now.plus(4, ChronoUnit.DAYS))
.stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));

// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(localDateZones(now.toLocalDate(), now.toLocalDate().plus(4, ChronoUnit.DAYS))
.stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));

日期加减

示例代码

1
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
String patternDate = "yyyy-MM-dd HH:mm:ss";

LocalDateTime now = LocalDateTime.of(2017, Month.DECEMBER, 30, 0, 0, 0);

// 当前时间: 2017-12-30 00:00:00
System.out.println("当前时间: " + format(now, patternDate));

// 30秒前: 2017-12-29 23:59:30
System.out.println("30秒前: " + format(now.plus(-30, ChronoUnit.SECONDS), patternDate));

// 5分钟后: 2017-12-30 00:05:00
System.out.println("5分钟后: " + format(now.plus(5, ChronoUnit.MINUTES), patternDate));

// 2天前: 2017-12-28 00:00:00
System.out.println("2天前: " + format(now.plus(-2, ChronoUnit.DAYS), patternDate));

// 2天后: 2018-01-01 00:00:00
System.out.println("2天后: " + format(now.plus(2, ChronoUnit.DAYS), patternDate));

// 1周后: 2018-01-06 00:00:00
System.out.println("1周后: " + format(now.plusWeeks(1), patternDate));

// 1月前: 2017-11-30 00:00:00
System.out.println("1月前: " + format(now.plus(-1, ChronoUnit.MONTHS), patternDate));

// 1月后: 2018-01-30 00:00:00
System.out.println("1月后: " + format(now.plus(1, ChronoUnit.MONTHS), patternDate));

// 1年后: 2018-12-30 00:00:00
System.out.println("1年后: " + format(now.plus(1, ChronoUnit.YEARS), patternDate));

日期推算

示例代码

1
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
String patternDate = "yyyy-MM-dd";

LocalDateTime now = LocalDateTime.of(2017, Month.DECEMBER, 30, 0, 0, 0);

// 当前时间: 2017-12-30
System.out.println("当前时间: " + format(now, patternDate) + " ,是否闰年: " + now.toLocalDate().isLeapYear());

// 当前月份: 十二月
System.out.println("当前月份: " + Month.from(now).getDisplayName(TextStyle.FULL, Locale.CHINA));

// 当前星期: 星期六
System.out.println("当前星期: " + DayOfWeek.from(now).getDisplayName(TextStyle.FULL, Locale.CHINA));

// 需要注意:java8提供的获取的本周第一天和本周最后一天是西方的界定方式, 第一天是周末, 最后一天是周六, 和中国的不太一样
// 本周初第一天:2017-12-24
System.out.println("本周初第一天: " + format(now.with(WeekFields.of(Locale.CHINA).dayOfWeek(),1L), patternDate));

// 本周最后一天:2017-12-30
System.out.println("本周最后一天: " + format(now.with(WeekFields.of(Locale.CHINA).dayOfWeek(),7L), patternDate));

// 本月初第一天:2017-12-01
System.out.println("本月初第一天: " + format(now.with(TemporalAdjusters.firstDayOfMonth()), patternDate));

// 本月最后一天:2017-12-31
System.out.println("本月最后一天: " + format(now.with(TemporalAdjusters.lastDayOfMonth()), patternDate));

// 本年最后一天:2017-01-01
System.out.println("本年最后一天: " + format(now.with(TemporalAdjusters.firstDayOfYear()), patternDate));

// 本年最后一天:2017-12-31
System.out.println("本年最后一天: " + format(now.with(TemporalAdjusters.lastDayOfYear()), patternDate));