|
@@ -0,0 +1,313 @@
|
|
|
|
|
+package com.cyksj.common.util;
|
|
|
|
|
+
|
|
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
|
|
+
|
|
|
|
|
+import java.time.Duration;
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
|
|
+import java.time.ZoneOffset;
|
|
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
|
|
+import java.time.temporal.TemporalAdjusters;
|
|
|
|
|
+import java.util.Calendar;
|
|
|
|
|
+import java.util.Date;
|
|
|
|
|
+import java.util.Locale;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * @author valor
|
|
|
|
|
+ * @date 2018/9/22 14:17
|
|
|
|
|
+ */
|
|
|
|
|
+public class Times {
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 一天的秒数
|
|
|
|
|
+ */
|
|
|
|
|
+ public static final int second_per_day = 86400;
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 一小时的毫秒数
|
|
|
|
|
+ */
|
|
|
|
|
+ public static final int millisecond_per_hour = 3600000;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 一个月的秒数
|
|
|
|
|
+ */
|
|
|
|
|
+ public static final int second_per_month = 259200;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 一分钟的毫秒数
|
|
|
|
|
+ */
|
|
|
|
|
+ public static final int millisecond_per_minute = 60000;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 默认时区
|
|
|
|
|
+ */
|
|
|
|
|
+// private static final ZoneId zoneId;
|
|
|
|
|
+// static {
|
|
|
|
|
+// zoneId = ZoneId.of("Asia/Shanghai");
|
|
|
|
|
+// }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 默认时区的时间偏移量
|
|
|
|
|
+ */
|
|
|
|
|
+ private static final ZoneOffset zoneOffSet;
|
|
|
|
|
+ static {
|
|
|
|
|
+ // 8小时的秒数 8 * 60 * 60
|
|
|
|
|
+ zoneOffSet = ZoneOffset.ofTotalSeconds(28800);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 时间格式化 枚举类
|
|
|
|
|
+ */
|
|
|
|
|
+ public enum Formatter {
|
|
|
|
|
+ DateTime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.US)),
|
|
|
|
|
+ ISO_8601(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)),
|
|
|
|
|
+ RFC_1123(DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US)),
|
|
|
|
|
+ DATAS(DateTimeFormatter.ofPattern("yyyy-MM-dd",Locale.US)),
|
|
|
|
|
+ DATA_YM(DateTimeFormatter.ofPattern("yyyy-MM",Locale.US)),
|
|
|
|
|
+ DATAS_ST(DateTimeFormatter.ofPattern("yyyy-MM-10",Locale.US)),
|
|
|
|
|
+ MSEC(DateTimeFormatter.ofPattern("yyyy-MM-dd HHmmssSSS",Locale.US)),
|
|
|
|
|
+ HOUR_MIN_SEC(DateTimeFormatter.ofPattern("HH:mm:ss",Locale.US)),
|
|
|
|
|
+ HOUR_MIN_SEC_MSEC(DateTimeFormatter.ofPattern("HH:mm:ss:SSS",Locale.US)),
|
|
|
|
|
+ YEAR_MONTH_DAY(DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss",Locale.US)),
|
|
|
|
|
+ DATE_YMD(DateTimeFormatter.ofPattern("yyyyMMdd",Locale.US)),
|
|
|
|
|
+ DATA_10H(DateTimeFormatter.ofPattern("yyyy-MM-dd 10:00:00", Locale.US)),
|
|
|
|
|
+ MONTH_DAY(DateTimeFormatter.ofPattern("MM/dd",Locale.US));
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private DateTimeFormatter formatter;
|
|
|
|
|
+
|
|
|
|
|
+ Formatter(DateTimeFormatter formatter) {
|
|
|
|
|
+ this.formatter = formatter;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public DateTimeFormatter getFormatter() {
|
|
|
|
|
+ return this.formatter;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 不允许外部实例化
|
|
|
|
|
+ */
|
|
|
|
|
+ private Times() { }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定日期字符串 按指定格式转换成timestamp
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long toTimestamp(String str, Formatter formatter) {
|
|
|
|
|
+ return toTimestamp(str, formatter, zoneOffSet);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定日期字符串 按指定格式转换成timestamp
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long toTimestamp(String str, Formatter formatter, ZoneOffset offset) {
|
|
|
|
|
+ return toDateTime(str, formatter).toEpochSecond(offset) * 1000L;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定timestamp 按指定格式 格式化时间
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String format(long time, Formatter formatter) {
|
|
|
|
|
+ return format(time, formatter, zoneOffSet);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定timestamp 按指定格式 格式化时间
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String format(long time, Formatter formatter, ZoneOffset offset) {
|
|
|
|
|
+ return format(toDateTime(time, offset), formatter);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定LocalDateTime 按指定格式 格式化时间
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String format(LocalDateTime time, Formatter formatter) {
|
|
|
|
|
+ return time.format(formatter.getFormatter());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定日期字符串 按指定格式转换成localDateTime
|
|
|
|
|
+ */
|
|
|
|
|
+ public static LocalDateTime toDateTime(String str, Formatter formatter) {
|
|
|
|
|
+ return LocalDateTime.parse(str, formatter.getFormatter());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定timestamp 转换成localDateTime
|
|
|
|
|
+ */
|
|
|
|
|
+ public static LocalDateTime toDateTime(long timestamp) {
|
|
|
|
|
+ return toDateTime(timestamp, zoneOffSet);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定timestamp 转换成localDateTime
|
|
|
|
|
+ */
|
|
|
|
|
+ public static LocalDateTime toDateTime(long timestamp, ZoneOffset offset) {
|
|
|
|
|
+ long secs = timestamp / 1000L;
|
|
|
|
|
+ return LocalDateTime.ofEpochSecond(secs, 0, offset);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断指定timestamp 是否是过去的时间
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean isPast(long time) {
|
|
|
|
|
+ return System.currentTimeMillis() > time;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断指定timestamp 是否是未来的时间
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean isFuture(long time) {
|
|
|
|
|
+ return System.currentTimeMillis() < time;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断当前timestamp 是否在某个时间段内
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean isInTime(long start, long end) {
|
|
|
|
|
+ return isInTime(System.currentTimeMillis(), start, end);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断指定timestamp 是否在某个时间段内
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean isInTime(long time, long start, long end) {
|
|
|
|
|
+ return start <= time && time <= end;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 计算两个日期相差的 毫秒数
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long between(LocalDateTime one, LocalDateTime another) {
|
|
|
|
|
+ return Duration.between(one, another).toMillis();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取今日零时timestamp
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long getZeroPoint() {
|
|
|
|
|
+ return getZeroPoint(0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取今日日期 格式 yyyy-MM-dd
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String getTodayStr(){
|
|
|
|
|
+ return format(getZeroPoint(0),Formatter.DATAS);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定与今日相差的天数 获取零时timestamp
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long getZeroPoint(int days) {
|
|
|
|
|
+ return getZeroPoint(days, zoneOffSet);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定与今日相差的天数 获取零时timestamp
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long getZeroPoint(int days, ZoneOffset zoneOffSet) {
|
|
|
|
|
+ return getZeroPoint(System.currentTimeMillis(), days, zoneOffSet);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定时间戳 获取零时timestamp
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long getZeroPoint(long timestamp) {
|
|
|
|
|
+ return getZeroPoint(timestamp, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定时间戳 获取零时timestamp
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long getZeroPoint(long timestamp, int days) {
|
|
|
|
|
+ return getZeroPoint(timestamp, days, zoneOffSet);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 指定时间戳 获取零时timestamp
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long getZeroPoint(long timestamp, int days, ZoneOffset zoneOffSet) {
|
|
|
|
|
+ int offset = zoneOffSet.getTotalSeconds();
|
|
|
|
|
+
|
|
|
|
|
+ long time = timestamp / 1000L + offset;
|
|
|
|
|
+ long point = time - time % second_per_day;
|
|
|
|
|
+
|
|
|
|
|
+ if (0 != days) {
|
|
|
|
|
+ point += days * second_per_day;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 计算时 传入的时区为标准
|
|
|
|
|
+ return (point - offset) * 1000L;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取当前时间的10号时间戳
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long getStartTime(long startTime){
|
|
|
|
|
+ Calendar c = Calendar.getInstance();
|
|
|
|
|
+ c.setTimeInMillis(startTime);
|
|
|
|
|
+ long l = Times.toTimestamp(Times.format(c.getTimeInMillis(),Times.Formatter.DATAS_ST) + " 00:00:00", Times.Formatter.DateTime);
|
|
|
|
|
+ if (c.getTimeInMillis() < l){
|
|
|
|
|
+ c.add(Calendar.MONTH, -1);
|
|
|
|
|
+ l = Times.toTimestamp(Times.format(c.getTimeInMillis(),Times.Formatter.DATAS_ST) + " 00:00:00", Times.Formatter.DateTime);
|
|
|
|
|
+ }
|
|
|
|
|
+ return l;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取当前时间的次月10号时间戳
|
|
|
|
|
+ */
|
|
|
|
|
+ public static long getEndTime(){
|
|
|
|
|
+ Calendar c = Calendar.getInstance();
|
|
|
|
|
+ long l = Times.toTimestamp(Times.format(c.getTimeInMillis(), Times.Formatter.DATAS_ST) + " 00:00:00", Times.Formatter.DateTime);
|
|
|
|
|
+ if (c.getTimeInMillis() >= l){
|
|
|
|
|
+ c.add(Calendar.MONTH, 1);
|
|
|
|
|
+ l = Times.toTimestamp(Times.format(c.getTimeInMillis(), Times.Formatter.DATAS_ST) + " 00:00:00", Times.Formatter.DateTime);
|
|
|
|
|
+ }
|
|
|
|
|
+ return l;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断选择的日期是否是本周
|
|
|
|
|
+ */
|
|
|
|
|
+ public static boolean isThisWeek(long time) {
|
|
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
|
|
+ calendar.setFirstDayOfWeek(Calendar.MONDAY);
|
|
|
|
|
+ int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
|
|
|
|
|
+ calendar.setTime(new Date(time));
|
|
|
|
|
+ int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);
|
|
|
|
|
+ return paramWeek == currentWeek;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 传入一个日期返回距今几年几天
|
|
|
|
|
+ * @param date
|
|
|
|
|
+ * @return 1年223天
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String getDaysOfYear(String date) {
|
|
|
|
|
+ String time = "";
|
|
|
|
|
+ LocalDate startDate = LocalDate.parse(date);
|
|
|
|
|
+ startDate = startDate.plusDays(-1L);
|
|
|
|
|
+ LocalDate endDate = LocalDate.parse(DateUtil.format(new Date(), "yyyy-MM-dd"));
|
|
|
|
|
+ LocalDate startDateOfYear = startDate.with(TemporalAdjusters.firstDayOfYear());
|
|
|
|
|
+ LocalDate endDateOfYear = endDate.with(TemporalAdjusters.firstDayOfYear());
|
|
|
|
|
+ long day1 = ChronoUnit.DAYS.between(startDate, endDate);
|
|
|
|
|
+ long year = ChronoUnit.YEARS.between(startDate, endDate);
|
|
|
|
|
+ long day2 = ChronoUnit.DAYS.between(startDateOfYear, endDateOfYear);
|
|
|
|
|
+ if (day2 > day1) {
|
|
|
|
|
+ endDateOfYear = endDateOfYear.minusYears(1);
|
|
|
|
|
+ day2 = ChronoUnit.DAYS.between(startDateOfYear, endDateOfYear);
|
|
|
|
|
+ }
|
|
|
|
|
+ long sub = day1 - day2;
|
|
|
|
|
+ if (year > 0) {
|
|
|
|
|
+ time = year + "年";
|
|
|
|
|
+ if (sub > 0) {
|
|
|
|
|
+ time = time + sub + "天";
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (sub > 0) {
|
|
|
|
|
+ time = sub + "天";
|
|
|
|
|
+ }
|
|
|
|
|
+ return time;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|