Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.dennisit.vplus.data.utils.DateTimeUtils Maven / Gradle / Ivy
/*--------------------------------------------------------------------------
* Copyright (c) 2010-2020, Elon.su All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the elon developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: Elon.su, you can also mail [email protected]
*--------------------------------------------------------------------------
*/
package com.github.dennisit.vplus.data.utils;
import com.github.dennisit.vplus.data.utils.date.ChineseDate;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.joda.time.Days;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Created by Elon.su on 17/9/16.
*/
@Slf4j
public class DateTimeUtils {
public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
public static final String PATTERN_DATE = "yyyy-MM-dd";
public static final String PATTERN_TIME = "HH:mm:ss";
/**
* 老 date 格式化
*/
public static final ConcurrentDateFormat DATETIME_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME);
public static final ConcurrentDateFormat DATE_FORMAT = ConcurrentDateFormat.of(PATTERN_DATE);
public static final ConcurrentDateFormat TIME_FORMAT = ConcurrentDateFormat.of(PATTERN_TIME);
/**
* java 8 时间格式化
*/
public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(PATTERN_DATETIME);
public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(PATTERN_DATE);
public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(PATTERN_TIME);
private static final String[] HANZI = {"壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾"};
private static final String[] DI_ZHI = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
private static final String[] TIAN_GAN = {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
public static final org.joda.time.LocalDate LOCAL_INIT_DATE = new org.joda.time.LocalDate(1970, 1, 1);
/**
* 标准日期格式
*/
public final static String NORM_DATE_PATTERN = "yyyy-MM-dd";
/**
* 标准时间格式
*/
public final static String NORM_TIME_PATTERN = "HH:mm:ss";
/**
* 标准日期时间格式
*/
public final static String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
/**
* HTTP头中日期时间格式
*/
public final static String HTTP_DATETIME_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";
/**
* 标准日期(不含时间)格式化器
*/
public final static SimpleDateFormat NORM_DATE_FORMAT = new SimpleDateFormat(NORM_DATE_PATTERN);
/**
* 标准时间格式化器
*/
public final static SimpleDateFormat NORM_TIME_FORMAT = new SimpleDateFormat(NORM_TIME_PATTERN);
/**
* 标准日期时间格式化器
*/
public final static SimpleDateFormat NORM_DATETIME_FORMAT = new SimpleDateFormat(NORM_DATETIME_PATTERN);
/**
* HTTP日期时间格式化器
*/
public final static SimpleDateFormat HTTP_DATETIME_FORMAT = new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US);
public static Date now() {
return new Date();
}
public static String lunarYearToGanZhi(int lunarYear) {
return TIAN_GAN[(lunarYear - 4) % 10] + DI_ZHI[(lunarYear - 4) % 12] + "年";
}
public static String lunarMonthToChinese(int month, boolean isleap) {
String prefix = isleap ? "润" : "";
if (month <= 10) {
return prefix + HANZI[month - 1] + "月";
} else {
return prefix + HANZI[9] + HANZI[month % 10 - 1] + "月";
}
}
public static String lunarDayToChinese(int day) {
if (day <= 10) {
return "初" + HANZI[day - 1];
} else if (day == 20) {
return "贰拾";
} else if (day == 30) {
return "叁拾";
} else {
return HANZI[day / 10 - 1] + HANZI[day % 10 - 1];
}
}
/**
* 24小时的时间转为对应的农历说法
*
* @param hour [0, 23]
* @return 农历文案
*/
public static String hourToChinese(int hour) {
if (hour == 23) {
return DI_ZHI[0] + "时";
} else {
return DI_ZHI[(hour + 1) / 2] + "时";
}
}
/**
* 阴历转字符串
*
* @param lunar 阴历
* @return 字符串描述
*/
public static String parseLunar(ChineseDate.Lunar lunar) {
StringBuilder builder = new StringBuilder();
builder.append(lunarYearToGanZhi(lunar.getLunarYear()));
builder.append(lunarMonthToChinese(lunar.getLunarMonth(), lunar.isIsleap()));
builder.append(lunarDayToChinese(lunar.getLunarDay()));
return builder.toString();
}
/**
* 获取当前的阴历日期
*
* @param containHour 小时
* @return 字符串描述
*/
public static String getNowLunarDate(boolean containHour) {
Calendar rightNow = Calendar.getInstance();
int year = rightNow.get(Calendar.YEAR);
int month = rightNow.get(Calendar.MONTH) + 1; //第一个月从0开始,所以得到月份+1
int day = rightNow.get(Calendar.DAY_OF_MONTH);
int hour = rightNow.get(Calendar.HOUR_OF_DAY);
ChineseDate.Solar solar = new ChineseDate.Solar(year, month, day);
ChineseDate.Lunar lunar = ChineseDate.solarToLunar(solar);
if (containHour) {
return parseLunar(lunar) + " " + hourToChinese(hour);
} else {
return parseLunar(lunar);
}
}
public static String getNowLunarDate() {
return getNowLunarDate(true);
}
/**
* 将 {@link LocalDateTime} 转换成 {@link Date}
*
* @param localDateTime {@link LocalDateTime} 待转换的日期
* @return 转换成Date结果
*/
@Deprecated
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} 结果
*/
@Deprecated
public static LocalDateTime from(Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
/**
* 获取{@link Date}在开始时间和结束时间内的日期时间段{@link Date}集合
*
* @param start 开始时间
* @param end 结束时间
* @return 时间天数集合
*/
public static List dateZones(Date start, Date end) {
return dateZones(from(start), from(end));
}
/**
* 获取 {@link LocalDate} 在开始时间和结束时间内的日期时间段 {@link LocalDate} 集合
*
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List 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 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 localDateZones(Date start, Date end) {
return localDateZones(from(start), from(end));
}
/**
* 获取 {@link LocalDate} 在开始时间和结束时间内的日期时间段 {@link LocalDate} 集合
*
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List 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 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());
}
/**
* 日期转换为Unix时间戳
*
* @param date 日期
* @return 秒数
*/
public static int date2Unixtime(Date date) {
return (int) (date.getTime() / 1000L);
}
/**
* 获取当前日期距离1970年多少天
*
* @param date 日期
* @return 距离1970年有多少天
*/
public static long getDaysTotal(Date date) {
return Days.daysBetween(LOCAL_INIT_DATE, org.joda.time.LocalDate.fromDateFields(date)).getDays();
}
/**
* 判断是否日期(年月日)有重叠
*
* @param zones 开始时间结束时间对
* @return 是否有天数重叠
*/
public static boolean isDayOverlap(List> zones) {
if (CollectionUtils.isEmpty(zones) || zones.size() <= 1) {
return false;
}
validateDateTimes(zones);
for (int i = 0; i < zones.size() - 1; i++) {
long starTime = getDaysTotal(zones.get(i).getLeft());
long endTime = getDaysTotal(zones.get(i).getRight());
for (int j = i + 1; j < zones.size(); j++) {
log.info(zones.get(i) + " == " + zones.get(i));
long jsTime = getDaysTotal(zones.get(j).getLeft());
long jeTime = getDaysTotal(zones.get(j).getRight());
if (!(jeTime < starTime || jsTime > endTime)) {
return true;
}
}
}
return false;
}
/**
* 判断是否日期时间(年月日时分秒)重叠
*
* @param zones 开始时间结束时间对
* @return 是否日期时间重叠
*/
public static boolean isDateTimeOverlap(List> zones) {
if (CollectionUtils.isEmpty(zones) || zones.size() <= 1) {
return false;
}
validateDateTimes(zones);
for (int i = 0; i < zones.size() - 1; i++) {
long starTime = zones.get(i).getLeft().getTime();
long endTime = zones.get(i).getRight().getTime();
for (int j = i + 1; j < zones.size(); j++) {
log.info(zones.get(i) + " == " + zones.get(i));
long jsTime = zones.get(j).getLeft().getTime();
long jeTime = zones.get(j).getRight().getTime();
if (!(jeTime < starTime || jsTime > endTime)) {
return true;
}
}
}
return false;
}
/**
* 校验时间段个贵姓
*
* @param zones
*/
private static void validateDateTimes(List> zones) {
if (CollectionUtils.isEmpty(zones)) {
return;
}
for (Pair timeZone : zones) {
if (null == timeZone) {
throw new IllegalArgumentException("时间段为空");
}
if (null == timeZone.getLeft() || null == timeZone.getRight()) {
throw new IllegalArgumentException("时间段为空");
}
if (timeZone.getRight().getTime() <= timeZone.getLeft().getTime()) {
throw new IllegalArgumentException("开始时间大于等于结束时间");
}
}
}
/**
* 获取当前年份的所有月份的第一天
*
* @return 日期集合
*/
public static List getNowYearFirstDayOfEachMonth() {
Calendar cal = Calendar.getInstance();
List list = Lists.newArrayList();
for (int i = 0; i < 12; i++) {
cal.set(Calendar.MONTH, i);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
list.add(cal.getTime());
}
return list;
}
public static Integer getHourMinutePeriod() {
return Calendar.getInstance().get(Calendar.HOUR_OF_DAY) * 60 + Calendar.getInstance().get(Calendar.MINUTE);
}
/*public static final long MILLIS_IN_ONE_MINUTE = 1000 * 60;
// public static final long MILLIS_IN_ONE_HOUR = MILLIS_IN_ONE_MINUTE * 60;
public static final long MILLIS_IN_ONE_DAY = MILLIS_IN_ONE_HOUR * 24;
public static final long MILLIS_IN_ONE_YEAR = MILLIS_IN_ONE_DAY * 365;*/
/**
* 原实现做的乘除法过多,影响效率,且几个方法的代码重复
*
* @param intervalMillis 据现在的时间间隔
* @return
*/
/**
* 日期时间格式化
*
* @param date 时间
* @return 格式化后的时间
*/
public static String formatDateTime(Date date) {
return DATETIME_FORMAT.format(date);
}
/**
* 日期格式化
*
* @param date 时间
* @return 格式化后的时间
*/
public static String formatDate(Date date) {
return DATE_FORMAT.format(date);
}
/**
* 时间格式化
*
* @param date 时间
* @return 格式化后的时间
*/
public static String formatTime(Date date) {
return TIME_FORMAT.format(date);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @param pattern 表达式
* @return 时间
*/
public static LocalDateTime parseDateTime(String dateStr, String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return parseDateTime(dateStr, formatter);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @param formatter DateTimeFormatter
* @return 时间
*/
public static LocalDateTime parseDateTime(String dateStr, DateTimeFormatter formatter) {
return LocalDateTime.parse(dateStr, formatter);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @return 时间
*/
public static LocalDateTime parseDateTime(String dateStr) {
return parseDateTime(dateStr, DATETIME_FORMATTER);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @param pattern 表达式
* @return 时间
*/
public static LocalDate parseDate(String dateStr, String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return parseDate(dateStr, formatter);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @param formatter DateTimeFormatter
* @return 时间
*/
public static LocalDate parseDate(String dateStr, DateTimeFormatter formatter) {
return LocalDate.parse(dateStr, formatter);
}
/**
* 将字符串转换为日期
*
* @param dateStr 时间字符串
* @return 时间
*/
public static LocalDate parseDate(String dateStr) {
return parseDate(dateStr, DATE_FORMATTER);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @param pattern 时间正则
* @return 时间
*/
public static LocalTime parseTime(String dateStr, String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return parseTime(dateStr, formatter);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @param formatter DateTimeFormatter
* @return 时间
*/
public static LocalTime parseTime(String dateStr, DateTimeFormatter formatter) {
return LocalTime.parse(dateStr, formatter);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @return 时间
*/
public static LocalTime parseTime(String dateStr) {
return parseTime(dateStr, TIME_FORMATTER);
}
}