package com.estate.expert.common.utils;
|
|
import com.google.common.collect.Lists;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.text.SimpleDateFormat;
|
import java.time.*;
|
import java.time.format.DateTimeFormatter;
|
import java.time.temporal.TemporalAdjusters;
|
import java.time.temporal.WeekFields;
|
import java.util.Calendar;
|
import java.util.Date;
|
import java.util.GregorianCalendar;
|
import java.util.List;
|
|
/**
|
* LocalDateTime 时间时区转换统一工具类
|
* @Author code
|
* @Date 2020/8/11 17:30
|
* @Version 1.0
|
*/
|
@Slf4j
|
public class DateConvertUtils {
|
|
/** 系统使用的时区 (默认为 CTT 中国上海时区) yml配置:shortZoneId:system 初始化是在: DefaultWebMvcConfig类中*/
|
public static String systemShortZoneId = "CTT";
|
|
/** 需要转换的时区 (默认转换为 PST美国洛杉矶时区) yml配置:shortZoneId:convert 初始化是在: DefaultWebMvcConfig类中*/
|
public static String convertShortZoneId = "PST";
|
|
/**
|
* 获取当前系统使用的时区ID
|
* @return
|
*/
|
public static String getSystemZoneId() {
|
return ZoneId.SHORT_IDS.get(systemShortZoneId);
|
}
|
|
/**
|
* 获取需要转换使用的时区ID
|
* @return
|
*/
|
public static String getConvertZoneId() {
|
return ZoneId.SHORT_IDS.get(convertShortZoneId);
|
}
|
|
/**
|
* 获取默认转换时区(convertShortZoneId)后的时间
|
* @return
|
*/
|
public static LocalDateTime getDefaultZoneTime() {
|
return LocalDateTime.now(Clock.system(ZoneId.of(getConvertZoneId())));
|
}
|
|
/**
|
* 根据传入的时间转换成指定配置时区(convertShortZoneId)后的时间
|
* @param localDateTime
|
* @return
|
*/
|
public static LocalDateTime getZoneTime(LocalDateTime localDateTime) {
|
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(getSystemZoneId())).withZoneSameInstant(ZoneId.of(getConvertZoneId()));
|
return zonedDateTime.toLocalDateTime();
|
}
|
|
/**
|
* 将指定时间的指定时区转换为目标时区的时间
|
* @param localDateTime 时间
|
* @param fromZone 指定时区
|
* @param toZone 目标时区
|
* @return
|
*/
|
public static LocalDateTime toZone(LocalDateTime localDateTime, String fromZone, String toZone) {
|
return toZone(localDateTime, ZoneId.of(fromZone), ZoneId.of(toZone));
|
}
|
|
/**
|
* 将指定时间的指定时区转换为目标时区的时间
|
* @param localDateTime 时间
|
* @param fromZone 指定时区
|
* @param toZone 目标时区
|
* @return
|
*/
|
public static LocalDateTime toZone(LocalDateTime localDateTime, ZoneId fromZone, ZoneId toZone) {
|
final ZonedDateTime zonedTime = localDateTime.atZone(fromZone);
|
final ZonedDateTime converted = zonedTime.withZoneSameInstant(toZone);
|
return converted.toLocalDateTime();
|
}
|
|
/**
|
* 获取指定配置时区(convertShortZoneId)本周周一的 字符串(yyyy-MM-dd)时间
|
* @return
|
*/
|
public static String getMondayOfThisWeek() {
|
LocalDateTime monday = getDefaultZoneTime().with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)).plusDays(1);
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
String date = dateTimeFormatter.format(monday);
|
return date;
|
}
|
|
/**
|
* 获取指定配置时区(convertShortZoneId)的周一的 LocalDateTime 时间
|
* @return
|
*/
|
public static LocalDateTime getMondayOfThisWeekToTime() {
|
LocalDateTime monday = getDefaultZoneTime().with(TemporalAdjusters.previous(DayOfWeek.MONDAY));
|
return LocalDateTime.of(monday.toLocalDate(), LocalTime.MIN);
|
}
|
|
/**
|
* 获取指定配置时区(convertShortZoneId)且 指定周的 周一的 LocalDateTime 时间
|
* @return
|
*/
|
public static LocalDateTime getMondayOfWeekToTime(WeekEnum weekEnum) {
|
LocalDateTime monday = getDefaultZoneTime().with(TemporalAdjusters.previous(DayOfWeek.SUNDAY));
|
return LocalDateTime.of(monday.plusDays(weekEnum.day).toLocalDate(), LocalTime.MIN);
|
}
|
|
public static void main(String[] args) {
|
|
System.out.println(getZoneCurrentDayMinTime(LocalDateTime.now()));
|
|
System.out.println(getZoneCurrentMonday(LocalDateTime.now()));
|
|
// System.out.println(getMondayOfThisWeekToTime());
|
System.out.println(getDefaultZoneTime());
|
System.out.println(getMondayOfThisWeek());
|
System.out.println(getLastMonday(LocalDateTime.now()));
|
System.out.println(getLocalDateTimeByDayOfWeek(DayOfWeek.WEDNESDAY));
|
System.out.println(getLocalDateTimeByDayOfWeek(DayOfWeek.SATURDAY));
|
System.out.println(getLocalDateTimeByDayOfWeek(DayOfWeek.SUNDAY));
|
}
|
|
/**
|
* 获取指定配置时区(convertShortZoneId)当前的年数(注意跨年的问题:已解决)
|
* @return
|
*/
|
public static int getWeekDeductionYear() {
|
LocalDateTime now = getDefaultZoneTime();
|
WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY,4);
|
int year = now.get(weekFields.weekBasedYear());
|
return year;
|
}
|
|
/**
|
* 获取指定配置时区(convertShortZoneId)当前年中的周数(注意跨年的问题:已解决)
|
* @return
|
*/
|
public static int getWeekDeductionYearWeek() {
|
LocalDateTime now = getDefaultZoneTime();
|
WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY,4);
|
int week = now.get(weekFields.weekOfWeekBasedYear());
|
return week;
|
}
|
|
/**
|
* 根据传入的时间不做时区转换进行格式转换(yyyy-MM-dd)
|
* @param localDateTime
|
* @return
|
*/
|
public static String noTimeZoneChangeFormat(LocalDateTime localDateTime) {
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
String date = dateTimeFormatter.format(localDateTime);
|
return date;
|
}
|
|
/**
|
* 根据传入的时间不做时区转换进行格式转换(yyyy-MM-dd)
|
* @param localDateTime
|
* @param pattern
|
* @return
|
*/
|
public static String noTimeZoneChangeFormat(LocalDateTime localDateTime, String pattern) {
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
|
String date = dateTimeFormatter.format(localDateTime);
|
return date;
|
}
|
|
/**
|
* 根据传入的时间不做时区转换进行格式转换(yyyy-MM-dd)
|
* @param localDate
|
* @return
|
*/
|
public static String noTimeZoneChangeFormat(LocalDate localDate) {
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
String date = localDate.format(dateTimeFormatter);
|
return date;
|
}
|
|
/**
|
* 根据传入的时间不做时区转换进行格式转换(yyyy-MM-dd)
|
* @param date
|
* @return
|
*/
|
public static String noTimeZoneChangeFormat(Date date) {
|
SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd");
|
String result = dateTimeFormatter.format(date);
|
return result;
|
}
|
|
/**
|
* 将传入的时间 转换成指定配置时区(convertShortZoneId)格式的字符数据
|
* @param localDateTime
|
* @param pattern
|
* @return
|
*/
|
public static String formatZone(LocalDateTime localDateTime, String pattern) {
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
|
String date = dateTimeFormatter.format(getZoneTime(localDateTime));
|
return date;
|
}
|
|
/**
|
* 将传入的时间 转换成指定配置时区(convertShortZoneId)指定格式(yyyy-MM-dd)的字符数据
|
* @param localDateTime
|
* @return
|
*/
|
public static String formatZone(LocalDateTime localDateTime) {
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
String date = dateTimeFormatter.format(getZoneTime(localDateTime));
|
return date;
|
}
|
|
/**
|
* 获取指定配置时区(convertShortZoneId)的当前时间,并转换成指定格式(yyyy-MM-dd)的字符数据
|
* @return
|
*/
|
public static String format() {
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
String date = dateTimeFormatter.format(getDefaultZoneTime());
|
return date;
|
}
|
|
/**
|
* 将传入的时间转换成 转换成指定格式(yyyy-MM-dd)的字符数据
|
* @param localDateTime
|
* @return
|
*/
|
@Deprecated
|
public static String format(LocalDateTime localDateTime) {
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
String date = dateTimeFormatter.format(localDateTime);
|
return date;
|
}
|
|
/**
|
* 将传入的时间转换成指定配置时区(convertShortZoneId)的 数字时间(yyyyMMdd)
|
* @param localDateTime
|
* @return
|
*/
|
public static Integer formatZoneToInt(LocalDateTime localDateTime) {
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
|
String date = dateTimeFormatter.format(getZoneTime(localDateTime));
|
return Integer.valueOf(date);
|
}
|
|
/**
|
* 将传入的时间转换成 数字时间(yyyyMMdd)
|
* @param localDateTime
|
* @return
|
*/
|
public static Integer formatToInt(LocalDateTime localDateTime) {
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
|
String date = dateTimeFormatter.format(localDateTime);
|
return Integer.valueOf(date);
|
}
|
|
/**
|
* 获取指定配置时区(convertShortZoneId)的当前时间的最小时间
|
* @return
|
*/
|
public static LocalDateTime getZoneDateMinTime(){
|
LocalDateTime now = getDefaultZoneTime().with(LocalTime.MIN);
|
return now;
|
}
|
|
/**
|
* 获取指定配置时区(convertShortZoneId)的当前时间的最大时间
|
* @return
|
*/
|
public static LocalDateTime getZoneDateMaxTime(){
|
LocalDateTime now = getDefaultZoneTime().with(LocalTime.MAX);
|
return now;
|
}
|
|
/**
|
* 获取传入当天的时间获取当天在转换时区后的开始时间
|
* @param localDateTime 传入配置的时区的时间
|
* @return
|
*/
|
public static LocalDateTime getZoneCurrentDayMinTime(LocalDateTime localDateTime) {
|
LocalDateTime with = getZoneTime(localDateTime).with(LocalTime.MIN);
|
LocalDateTime toZoneTime = toZone(with, ZoneId.SHORT_IDS.get(convertShortZoneId), ZoneId.SHORT_IDS.get(systemShortZoneId));
|
return toZoneTime;
|
}
|
|
/**
|
* 获取上周 周一的开始时间
|
* @param localDateTime 传入配置的时区的时间
|
* @return
|
*/
|
public static LocalDateTime getLastMonday(LocalDateTime localDateTime) {
|
LocalDateTime with = localDateTime.toLocalDate().minusWeeks(1L).with(DayOfWeek.MONDAY).atStartOfDay();
|
LocalDateTime toZoneTime = toZone(with, ZoneId.SHORT_IDS.get(convertShortZoneId), ZoneId.SHORT_IDS.get(systemShortZoneId));
|
return toZoneTime;
|
}
|
|
|
/**
|
* 获取上周 周一的开始时间
|
* @param localDateTime 传入配置的时区的时间
|
* @return
|
*/
|
public static LocalDateTime getZoneLastMonday(LocalDateTime localDateTime) {
|
LocalDateTime with = localDateTime.toLocalDate().minusWeeks(1L).with(DayOfWeek.MONDAY).atStartOfDay();
|
LocalDateTime toZoneTime = toZone(with, ZoneId.SHORT_IDS.get(convertShortZoneId), ZoneId.SHORT_IDS.get(systemShortZoneId));
|
return toZoneTime;
|
}
|
|
/**
|
* 获取本周 周一的开始时间
|
* @param localDateTime 传入配置的时区的时间
|
* @return
|
*/
|
public static LocalDateTime getZoneCurrentMonday(LocalDateTime localDateTime) {
|
LocalDateTime with = localDateTime.toLocalDate().with(DayOfWeek.MONDAY).atStartOfDay();
|
LocalDateTime toZoneTime = toZone(with, ZoneId.SHORT_IDS.get(convertShortZoneId), ZoneId.SHORT_IDS.get(systemShortZoneId));
|
return toZoneTime;
|
}
|
|
/**
|
* 获取本周指定周几的开始时间
|
* @param dayOfWeek
|
* @return
|
*/
|
public static LocalDateTime getLocalDateTimeByDayOfWeek(DayOfWeek dayOfWeek){
|
LocalDateTime with = getDefaultZoneTime().toLocalDate().with(dayOfWeek).atStartOfDay();
|
LocalDateTime toZoneTime = toZone(with, ZoneId.SHORT_IDS.get(convertShortZoneId), ZoneId.SHORT_IDS.get(systemShortZoneId));
|
return toZoneTime;
|
}
|
|
|
/**
|
* 获取上周 周日的结束时间
|
* @param localDateTime 传入配置的时区的时间
|
* @return
|
*/
|
public static LocalDateTime getLastSunday(LocalDateTime localDateTime) {
|
LocalDateTime with = localDateTime.toLocalDate().minusWeeks(1L).with(DayOfWeek.SUNDAY).plusDays(1).atStartOfDay();
|
LocalDateTime toZoneTime = toZone(with, ZoneId.SHORT_IDS.get(convertShortZoneId), ZoneId.SHORT_IDS.get(systemShortZoneId));
|
return toZoneTime;
|
}
|
|
/**
|
* 获取两个时间相差的秒数
|
* @param startTime
|
* @param endTime
|
* @return
|
*/
|
public static Long getTimeDifference(LocalDateTime startTime, LocalDateTime endTime) {
|
Duration duration = Duration.between(startTime, endTime);
|
return duration.getSeconds();
|
}
|
|
/**
|
* 获取指定时间的时间戳(单位:秒)
|
* @param localDateTime
|
* @return
|
*/
|
public static Long getTimeSeconds(LocalDateTime localDateTime) {
|
Long seconds = localDateTime.toEpochSecond(ZoneOffset.of("+8"));
|
return seconds;
|
}
|
|
/**
|
* 根据传入时区的两个时间 获取两个日期相差的周数
|
*
|
* @param startDate - 开始时间(需要自己转换时区)
|
* @param endDate - 结束时间(需要自己转换时区)
|
* @return
|
*/
|
public static int getWeeksBetweenTime(LocalDateTime startDate, LocalDateTime endDate) {
|
Calendar dateFrom = GregorianCalendar.from(ZonedDateTime.of(startDate, ZoneId.systemDefault()));
|
//设置日历
|
Calendar dateTo = GregorianCalendar.from(ZonedDateTime.of(endDate, ZoneId.systemDefault()));
|
//获取年份
|
int yearFrom = dateFrom.get(Calendar.YEAR);
|
int yearTo = dateTo.get(Calendar.YEAR);
|
//获取日期所在年的周数
|
int weekOfYearFrom = dateFrom.get(Calendar.WEEK_OF_YEAR);
|
if (weekOfYearFrom == 1 && dateFrom.get(Calendar.MONTH) == Calendar.DECEMBER) {
|
//腊月最后几天的周数可能为1
|
weekOfYearFrom = getWeeksInYear(yearFrom, true);
|
}
|
int weekOfYearTo = dateTo.get(Calendar.WEEK_OF_YEAR);
|
if (weekOfYearTo == 1 && dateTo.get(Calendar.MONTH) == Calendar.DECEMBER) {
|
weekOfYearTo = getWeeksInYear(yearTo, true);
|
}
|
//同年直接返回
|
if (yearFrom == yearTo) {
|
return weekOfYearTo - weekOfYearFrom;
|
}
|
//不同年:
|
int betweenWeeks = weekOfYearTo;
|
int betweenYears = yearTo - yearFrom;
|
for (int i = 1; i <= betweenYears ; i++) {
|
betweenWeeks += getWeeksInYear(yearFrom+i, false);
|
}
|
betweenWeeks -= weekOfYearFrom;
|
return betweenWeeks;
|
}
|
|
/**
|
* 获取 某 年共有几周,
|
* @param year - 年份
|
* @param containLastDays - 腊月最后几天不满一周的,是否算为一周
|
* @return
|
*/
|
public static int getWeeksInYear(int year, boolean containLastDays){
|
Calendar calendar = Calendar.getInstance();
|
calendar.set(year, Calendar.DECEMBER,31);
|
int i = calendar.get(Calendar.WEEK_OF_YEAR);
|
if(i == 1 && containLastDays){
|
i = 53;
|
}
|
if(i != 53){
|
i = 52;
|
}
|
return i;
|
}
|
|
/**
|
* 获取传入时间获取传入时间当前所在周的周一的时间
|
* @param localDateTime
|
* @return
|
*/
|
public static LocalDateTime getCurrentMonday(LocalDateTime localDateTime) {
|
return localDateTime.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)).plusDays(1).with(LocalTime.MIN);
|
}
|
|
|
// /**
|
// * 获取传入时间的上周周一的日期时间
|
// * @param localDateTime
|
// * @return
|
// */
|
// public static LocalDate getLastMonday(LocalDateTime localDateTime) {
|
// LocalDate now = localDateTime.toLocalDate();
|
// LocalDate todayOfLastWeek = now.minusDays(7);
|
// LocalDate monday = todayOfLastWeek.with(TemporalAdjusters.previous(DayOfWeek.MONDAY));
|
// return monday;
|
// }
|
|
/**
|
* 根据配置的时区 和指定周枚举值 获取周的所有日期时间
|
* @return
|
*/
|
public static List<AllDaysOfTheWeekVo> getAllDaysOfWeekByShortZoneId(WeekEnum weekEnum) {
|
if(weekEnum == null) {
|
return Lists.newArrayList();
|
}
|
//根据时区来进行判断 如果是美国的时区的话 需要减去一天,其他时区暂时不做扣减,后续需要进行扣减的时间需要在 AllDaysOfTheWeekMinusDaysEnum 枚举中进行配置
|
return getAllDaysOfWeek(weekEnum, AllDaysOfTheWeekMinusDaysEnum.getMinusDays(convertShortZoneId));
|
}
|
|
/**
|
* 获取指定周内的所有日期时间
|
* @param weekEnum
|
* @param minusDays
|
* @return
|
*/
|
private static List<AllDaysOfTheWeekVo> getAllDaysOfWeek(WeekEnum weekEnum, int minusDays) {
|
List<LocalDateTime> days = Lists.newArrayList();
|
days.add(getDefaultZoneTime().with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)).plusDays(weekEnum.day).plusDays(1).minusDays(minusDays).with(LocalTime.MIN));
|
days.add(getDefaultZoneTime().with(TemporalAdjusters.next(DayOfWeek.MONDAY)).plusDays(weekEnum.day).minusDays(6).minusDays(minusDays).with(LocalTime.MIN));
|
days.add(getDefaultZoneTime().with(TemporalAdjusters.next(DayOfWeek.MONDAY)).plusDays(weekEnum.day).minusDays(5).minusDays(minusDays).with(LocalTime.MIN));
|
days.add(getDefaultZoneTime().with(TemporalAdjusters.next(DayOfWeek.MONDAY)).plusDays(weekEnum.day).minusDays(4).minusDays(minusDays).with(LocalTime.MIN));
|
days.add(getDefaultZoneTime().with(TemporalAdjusters.next(DayOfWeek.MONDAY)).plusDays(weekEnum.day).minusDays(3).minusDays(minusDays).with(LocalTime.MIN));
|
days.add(getDefaultZoneTime().with(TemporalAdjusters.next(DayOfWeek.MONDAY)).plusDays(weekEnum.day).minusDays(2).minusDays(minusDays).with(LocalTime.MIN));
|
days.add(getDefaultZoneTime().with(TemporalAdjusters.next(DayOfWeek.MONDAY)).plusDays(weekEnum.day).minusDays(1).minusDays(minusDays).with(LocalTime.MIN));
|
List<AllDaysOfTheWeekVo> voList = Lists.newArrayList();
|
days.forEach(day -> {
|
AllDaysOfTheWeekVo vo = new AllDaysOfTheWeekVo();
|
vo.setIntDayTime(formatToInt(day));
|
vo.setDayTime(day);
|
voList.add(vo);
|
});
|
return voList;
|
}
|
|
|
/**
|
* 获取指定年、周数的日期 (参考:https://blog.csdn.net/weixin_44919928/article/details/100008249)
|
* @param year
|
* @param num
|
* @param dayOfWeek(MONDAY TUESDAY)
|
* @return
|
*/
|
public static LocalDate getDateByYearAndWeekNumAndDayOfWeekParam(Integer year, Integer num, DayOfWeek dayOfWeek) {
|
//周数小于10在前面补个0
|
String numStr = num < 10 ? "0" + String.valueOf(num) : String.valueOf(num);
|
//2019-W01-01获取第一周的周一日期,2019-W02-07获取第二周的周日日期
|
String weekDate = String.format("%s-W%s-%s", year, numStr, dayOfWeek.getValue());
|
return LocalDate.parse(weekDate, DateTimeFormatter.ISO_WEEK_DATE);
|
}
|
|
/**
|
* 周类型枚举
|
*/
|
public enum WeekEnum {
|
/**
|
* 上周、本周、下周
|
*/
|
PREVIOUS_WEEK(-6),
|
THIS_WEEK(1),
|
NEXT_WEEK(8),
|
;
|
|
int day;
|
|
WeekEnum(int day) {
|
this.day = day;
|
}
|
}
|
|
public enum AllDaysOfTheWeekMinusDaysEnum {
|
/**
|
* PST 美国时间的周一是 中国时间的周日
|
* CTT 中国时间
|
* */
|
PST(1),
|
CTT(0),
|
;
|
|
int minusDays;
|
|
AllDaysOfTheWeekMinusDaysEnum(int minusDays) {
|
this.minusDays = minusDays;
|
}
|
|
public static int getMinusDays(String shortZoneId) {
|
for (AllDaysOfTheWeekMinusDaysEnum allDaysOfTheWeekMinusDaysEnum : AllDaysOfTheWeekMinusDaysEnum.values()) {
|
if(allDaysOfTheWeekMinusDaysEnum.name().equals(shortZoneId)) {
|
return allDaysOfTheWeekMinusDaysEnum.minusDays;
|
}
|
}
|
return 0;
|
}
|
}
|
|
/**
|
* 周的所有日期时间对象
|
*/
|
public static class AllDaysOfTheWeekVo {
|
/**
|
* 数字时间 yyyyMMdd
|
*/
|
private Integer intDayTime;
|
private LocalDateTime dayTime;
|
|
public Integer getIntDayTime() {
|
return intDayTime;
|
}
|
|
public void setIntDayTime(Integer intDayTime) {
|
this.intDayTime = intDayTime;
|
}
|
|
public LocalDateTime getDayTime() {
|
return dayTime;
|
}
|
|
public void setDayTime(LocalDateTime dayTime) {
|
this.dayTime = dayTime;
|
}
|
}
|
}
|