DateUtils :
写代码时最常见的“兄弟”——时间处理工具类DateUtils
首先,我们需要先准备几样“东西”:
// 时区
public static final int DEFAULT_TIME_ZONE = 0;
// 中国时区
public static final int CHINA_TIME_ZONE = 8;
+++++++++划重点:
常见时间格式:
private static final String[] prototypePatterns =
{ "yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd HH:mm", "HH:mm:ss.SSS", "yyyy-MM-dd", "dd-MM-yyyy",
"yy-MM-dd", "MM-dd-yyyy", "HH:mm:ss","HH:mm"
};
public static final DateTimeFormatter DATE_TIME_FORMATTER
= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofPattern("yyyy-MM-dd");
//东八区上海时区
public static final ZoneId CHINA_ZONE_ID = ZoneId.of("Asia/Shanghai");
/**
* 获取东8区的某一天的开始时间和结束时间
*
* @param time
* @return Instant[]
*/
public static Instant[] getDayStartTimeAndEndTime(Instant time) {
//获取北京时间的零点
ZoneId zoneId = CHINA_ZONE_ID;
LocalDateTime localDateTime = LocalDateTime.ofInstant(
time, zoneId);
//获取当天的开始时间
Instant minTime = localDateTime.toLocalDate()
.atStartOfDay(zoneId).toInstant();
//获取当天的结束时间
Instant maxTime = localDateTime.toLocalDate()
.atStartOfDay(zoneId).plusDays(1L).plusSeconds(-1L).toInstant();
return new Instant[]{minTime, maxTime};
}
目录
获取东8区的某个月的开始时间和结束时间
/**
* 获取东8区的某个月的开始时间和结束时间
*
* @param time
* @return
*/
public static Instant[] getMonthStartTimeAndEndTime(Instant time) {
LocalDateTime LocalBegin = time.atZone(CHINA_ZONE_ID).toLocalDateTime();
Instant minTime = LocalBegin.minusDays(LocalBegin.getDayOfMonth())
.toLocalDate().atStartOfDay(CHINA_ZONE_ID).toInstant();
Instant maxTime = LocalBegin.minusDays(LocalBegin.getDayOfMonth())
.minus(-1, ChronoUnit.MONTHS)
.toLocalDate().atStartOfDay(CHINA_ZONE_ID)
.minus(1L,ChronoUnit.MILLIS).toInstant();
return new Instant[]{minTime, maxTime};
}
判断两个Instant类型的时间,是否为同一天
/**
* 是否为同一天
*
* @param date1
* @param date2
* @return
*/
public static boolean isSameDate(Instant date1, Instant date2) {
ZoneId zoneId = CHINA_ZONE_ID;
LocalDate localDate1 = LocalDateTime.ofInstant(date1, zoneId).toLocalDate();
LocalDate localDate2 = LocalDateTime.ofInstant(date2, zoneId).toLocalDate();
return localDate1.compareTo(localDate2) == 0;
}
接下来就是最刺激的类型互转了:
1、Instant转为(String)类型
/**
* Instant转中国标准时间
*
* @param confirmTime
* @return
*/
public static String toChinaTimeFormat(Instant confirmTime) {
if (confirmTime == null) {
return null;
}
return DATE_TIME_FORMATTER.format(
LocalDateTime.ofInstant(confirmTime, CHINA_ZONE_ID)
);
}
public void test(){
String s = toChinaTimeFormat(Instant.now());
System.out.println(s);
}
输出:2021-08-05 17:17:05
// DATE_TIME_FORMATTER是前面设置的日期格式哦,也可以换别的!
//本来想解释一下ofInstant()源码的,但网上仿佛更全面,有兴趣的同学可以百度
2、LocalDate和Instant类型互转
/**
* localDateToInstant
* @param date
* @return
*/
public static Instant localDateToInstant(LocalDate date) {
ZoneId zone = ZoneId.systemDefault();
return date.atStartOfDay().atZone(zone).toInstant();
}
@Test
public void test(){
Instant instant = localDateToInstant(LocalDate.now());
System.out.println(instant);
}
输出结果:2021-08-04T16:00:00Z (采用的是系统默认的时区)
注:LocalDate.now()获取的是当天日期,转还为Instant时,是从当日0点算起的
/**
* instantToLocalDate
* @param instant
* @return
*/
public static LocalDate instantToLocalDate(Instant instant) {
ZoneId zone = ZoneId.systemDefault();
return instant.atZone(zone).toLocalDate();
}
输出结果:2021-08-05 (采用的是指定的时区)
3.Date和Instant类型互转
/**
* date2Instant
* @param date
* @return
*/
public static Instant date2Instant(Date date){
if(date == null){
return null;
}
return Instant.ofEpochMilli(date.getTime());
}
/**
* instant2Date
* @param instant
* @return
*/
public static Date instant2Date(Instant instant){
if(instant == null){
return null;
}
return Date.from(instant);
}
4.Instant和LocalDateTime互转
/**
* instant2LocalDateTime
* @param instant
* @return
*/
public static LocalDateTime instant2LocalDateTime(Instant instant){
if(instant == null){
return null;
}
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}
/**
* instant2LocalDateTime
* @param instant
* @return
*/
public static LocalDateTime instant2LocalDate(Instant instant){
if(instant == null){
return null;
}
return instant2LocalDateTime(instant).toLocalDateTime();
}
5.LocalDate和LocalDateTime转为Date
/**
* LocalDateTime转换为Date
* @param localDateTime
*/
public static Date localDateTime2Date(LocalDateTime localDateTime){
if(localDateTime == null){
return null;
}
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = localDateTime.atZone(zoneId);
return Date.from(zdt.toInstant());
}
/**
* LocalDate转换为Date
* @param localDate
*/
public static Date localDate2Date(LocalDate localDate){
if(localDate == null){
return null;
}
ZoneId zoneId = ZoneId.systemDefault();
Instant instant = localDate.atStartOfDay().atZone(zoneId).toInstant();
return Date.from(instant);
}
=====================================================
时间常用业务
6.计算生日
/**
* 获取年龄
*
* @param birthLocalDate
* @return
* @throws Exception
*/
public static int getAge(LocalDate birthLocalDate) {
Date birthDay = new Date(DateUtils.localDateToInstant(birthLocalDate).toEpochMilli());
Calendar cal = Calendar.getInstance();
if (cal.before(birthDay)) {
throw new IllegalArgumentException(
"The birthDay is before Now.It's unbelievable!");
}
int yearNow = cal.get(Calendar.YEAR);
int monthNow = cal.get(Calendar.MONTH);
int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
cal.setTime(birthDay);
int yearBirth = cal.get(Calendar.YEAR);
int monthBirth = cal.get(Calendar.MONTH);
int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
int age = yearNow - yearBirth;
if (monthNow <= monthBirth) {
if (monthNow == monthBirth) {
if (dayOfMonthNow < dayOfMonthBirth) {
age--;
}
} else {
age--;
}
}
return age;
}
7.只保留日期的Instant
/**
* 只保留日期
*
* @param datetime 带时间的
* @return 去掉时间的时间
*/
public static Instant truncatedToDate(Instant datetime) {
return datetime.truncatedTo(ChronoUnit.DAYS);
}
8.今天星期天,明天星期几呢
/**
* 获取下一天的星期几, LocalDateTime.dayOfWeek().getValue() 1~7
*
* @param dow 当前星期几
* @return 下一天星期几
*/
public static Integer nextDayOfWeekValue(Integer dow) {
return dow == 7 ? 1 : dow + 1;
}
9.获取最大的Instant
/**
* 获取最大的Instant
* @param instants
* @return
*/
public static Instant getMaxInstant(Instant... instants) {
if(instants == null || instants.length == 0){
return null;
}
Instant result = null;
for (Instant date : instants) {
if(date == null){
continue;
}
if(result == null || date.compareTo(result) > 0){
result = date;
}
}
return result;
}
获取当前天零点的格林威治时间:
例如: 当天零点 2021-11-03 00:00:00 格林威治时间:2021-11-02 16:00:00
LocalDateTime localDateTime = LocalDateTime.ofInstant(
Instant.now(), UTC);
Instant zeroToday = localDateTime.toLocalDate()
.atStartOfDay(UTC).toLocalDateTime().minusHours(8).toInstant(UTC);
// 比较Instant时间
attendanceRecordsDTO.getAllowCheckTime().isBefore(attendanceRecordsDTO.getUserCheckTime())
// 时间加(分钟)
attendanceRecords.getBaseCheckTime().plusMillis(TimeUnit.MINUTES.toMillis(flexibleSettings.getLate().getArrive()))
// 时间减(分钟)
attendanceRecords.getBaseCheckTime().minusMillis(TimeUnit.MINUTES.toMillis(flexibleSettings.getLate().getArrive()))
// 计算两个时间相差多少分钟,结果为long型
ChronoUnit.MINUTES.between(Instant ,Instant);