import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class Timestamp {
/*** 单位(秒) 60*/
public static final int MINUTE_SECONDS = 60;
/*** 单位(秒) 3600*/
public static final int HOUR_SECONDS = 60 * MINUTE_SECONDS;
/*** 单位(秒) 86400*/
public static final int DAY_SECONDS = 24 * HOUR_SECONDS;
/*** 单位(秒) 604800*/
public static final int WEEK_SECONDS = 7 * DAY_SECONDS;
/*** 本地时区偏移量 */
private static final ZoneOffset LOCAL_ZONE_OFFSET = ZoneOffset.ofHours(8);
/*** 时间week字段 */
private static final WeekFields WEEK_FIELDS = WeekFields.of(Locale.CHINA);
/**
* 时间戳
*/
protected int timestamp;
private Timestamp() {
this.timestamp = toTimestamp(LocalDateTime.now());
}
private Timestamp(int timestamp) {
this.timestamp = timestamp;
}
public int get() {
return timestamp;
}
/**
* 获取当前时间戳
*
* @return 当前时间戳
*/
public static Timestamp of() {
return new Timestamp();
}
/**
* 通过时间戳获取时间戳对象
*
* @return 时间戳对象
*/
public static Timestamp of(int timestamp) {
return new Timestamp(timestamp);
}
/**
* 根据年月日获取X7Timestamp对象,默认是当天00:00
*
* @param year 年
* @param month 月
* @param day 日
* @return X7Timestamp对象
*/
public static Timestamp ofDay(int year, int month, int day) {
LocalDateTime ldt = LocalDateTime.of(year, month, day, 0, 0, 0);
return new Timestamp(toTimestamp(ldt));
}
/**
* 获取某年某月的第一天的零点
*
* @param year 某年
* @param month 某月
* @return 某年某月的第一天的零点对应的X7Timestamp对象
*/
public static Timestamp ofMonth(int year, int month) {
LocalDateTime ldt = LocalDateTime.of(year, month, 1, 0, 0, 0);
return new Timestamp(toTimestamp(ldt));
}
/**
* 根据年和第几周获取X7Timestamp对象,默认是那一周第一天的00:00(!!!可能是上个月的日期!!!)
*
* @param year 年
* @param week 当年第几周
* @return X7Timestamp对象
*/
public static Timestamp ofWeek(int year, int week) {
LocalDateTime ldt = LocalDateTime.of(year, 1, 1, 0, 0)
.with(WEEK_FIELDS.weekOfYear(), week)
.with(WEEK_FIELDS.dayOfWeek(), 2);
return new Timestamp(toTimestamp(ldt));
}
/**
* 根据年月第几周获取X7Timestamp对象,默认是那一周第一天的00:00(!!!可能是上个月的日期!!!)
*
* @param year 年
* @param month 月
* @param week 当月第几周
* @return X7Timestamp对象
*/
public static Timestamp ofWeek(int year, int month, int week) {
LocalDateTime ldt = LocalDateTime.of(year, month, 1, 0, 0)
.with(WEEK_FIELDS.weekOfMonth(), week)
.with(WEEK_FIELDS.dayOfWeek(), 2);
return new Timestamp(toTimestamp(ldt));
}
/**
* 根据年获取X7Timestamp对象,默认是这一年第一天当天00:00
*
* @param year 年
* @return X7Timestamp对象
*/
public static Timestamp ofYear(int year) {
int timestamp = toTimestamp(LocalDateTime.of(year, 1, 1, 0, 0, 0));
return new Timestamp(timestamp);
}
/**
* 通过日期字符串获取时间戳对象
*
* @param date 日期字符串
* @param format 日期格式字符串
* @return 时间戳对象
*/
public static Timestamp ofDate(String date, String format) {
DateTimeFormatter df =
new DateTimeFormatterBuilder()
.appendPattern(format)
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
return new Timestamp(toTimestamp(LocalDateTime.parse(date, df)));
}
/**
* 通过日期字符串获取时间戳对象
*
* @param date 日期字符串
* @param ft 日期格式模板
* @return 时间戳对象
*/
public static Timestamp ofDate(String date, TimeFormat ft) {
return new Timestamp(toTimestamp(LocalDateTime.parse(date, ft.getFormatter())));
}
/**
* 以YYYY-MM-DD格式化时间戳
*
* @return 格式化字符串
*/
public final String toDate() {
return toLocalDateTime(timestamp).format(TimeFormat.YYYY_MM_DD.getFormatter());
}
/**
* 格式化时间戳
*
* @param ft 格式化模板
* @return 格式化字符串
*/
public final String toDate(TimeFormat ft) {
return toLocalDateTime(timestamp).format(ft.getFormatter());
}
/**
* 格式化时间戳
*
* @param format 日期格式字符串
* @return 格式化字符串
*/
public final String toDate(String format) {
return DateTimeFormatter.ofPattern(format).format(Timestamp.toLocalDateTime(timestamp));
}
/**
* 获取当前时间戳对应的 LocalDateTime 对象
*
* @return LocalDateTime 对象
*/
public final LocalDateTime getLocalDateTime() {
return toLocalDateTime(timestamp);
}
/**
* 在当前时间戳的基础上 + years月
*
* @param years 秒
*/
public Timestamp plusYears(int years) {
timestamp = toTimestamp(toLocalDateTime(timestamp).plusYears(years));
return this;
}
/**
* 在当前时间戳的基础上 + months月
*
* @param months 秒
*/
public Timestamp plusMonths(int months) {
timestamp = toTimestamp(toLocalDateTime(timestamp).plusMonths(months));
return this;
}
/**
* 在当前时间戳的基础上 + days天
*
* @param days 天数
*/
public Timestamp plusDays(int days) {
timestamp = timestamp + days * DAY_SECONDS;
return this;
}
/**
* 在当前时间戳的基础上 + hours小时数
*
* @param hours 小时数
*/
public Timestamp plusHours(int hours) {
timestamp = timestamp + hours * HOUR_SECONDS;
return this;
}
/**
* 在当前时间戳的基础上 + minutes分钟数
*
* @param minutes 分钟数
*/
public Timestamp plusMinutes(int minutes) {
timestamp = timestamp + minutes * MINUTE_SECONDS;
return this;
}
/**
* 在当前时间戳的基础上 + seconds秒
*
* @param seconds 秒
*/
public Timestamp plusSeconds(int seconds) {
timestamp = timestamp + seconds;
return this;
}
/**
* 获取当前时间所在时间周期的开始时间戳对象
*
* @param cycle 周期
* @return 时间戳对象
*/
public Timestamp getStart(TimeCycle cycle) {
LocalDateTime startDateTime;
int startTimestamp;
switch (cycle) {
case YEAR:
startDateTime = getLocalDateTime()
.with(TemporalAdjusters.firstDayOfYear())
.withHour(0).withMinute(0).withSecond(0);
return Timestamp.of(toTimestamp(startDateTime));
case MONTH:
startDateTime = getLocalDateTime()
.with(TemporalAdjusters.firstDayOfMonth())
.withHour(0).withMinute(0).withSecond(0);
return Timestamp.of(toTimestamp(startDateTime));
case WEEK:
int week = getLocalDateTime().getDayOfWeek().getValue();
startDateTime = getLocalDateTime().minusDays(week - 1).withHour(0).withMinute(0).withSecond(0);
return Timestamp.of(toTimestamp(startDateTime));
case DAY:
startTimestamp = getZero(timestamp);
return Timestamp.of(startTimestamp);
case HOUR:
startTimestamp = timestamp - (timestamp - getZero(timestamp)) % HOUR_SECONDS;
return Timestamp.of(startTimestamp);
case MINUTE:
startTimestamp = timestamp - timestamp % MINUTE_SECONDS;
return Timestamp.of(startTimestamp);
case SECOND:
default:
return this;
}
}
/**
* 获取当前时间所在时间周期的结束时间戳对象
*
* @param cycle 周期
* @return 时间戳对象
*/
public Timestamp getEnd(TimeCycle cycle) {
LocalDateTime endDateTime;
switch (cycle) {
case YEAR:
endDateTime = getLocalDateTime()
.with(TemporalAdjusters.lastDayOfYear())
.withHour(0).withMinute(0).withSecond(0);
return Timestamp.of(toTimestamp(endDateTime) + DAY_SECONDS - 1);
case MONTH:
endDateTime = getLocalDateTime()
.with(TemporalAdjusters.lastDayOfMonth())
.withHour(0).withMinute(0).withSecond(0);
return Timestamp.of(toTimestamp(endDateTime) + DAY_SECONDS - 1);
case WEEK:
return Timestamp.of(getStart(TimeCycle.WEEK).timestamp + WEEK_SECONDS - 1);
case DAY:
return Timestamp.of(getStart(TimeCycle.DAY).timestamp + DAY_SECONDS - 1);
case HOUR:
return Timestamp.of(getStart(TimeCycle.HOUR).timestamp + HOUR_SECONDS - 1);
case MINUTE:
return Timestamp.of(getStart(TimeCycle.MINUTE).timestamp + MINUTE_SECONDS - 1);
case SECOND:
default:
return this;
}
}
/**
* 这个时间对象范围内有多少天
*
* @return 这个时间对象范围内有多少天
*/
public int days(TimeCycle cycle) {
return (getEnd(cycle).timestamp + 1 - getStart(cycle).timestamp) / DAY_SECONDS;
}
/**
* 获取当前对象的开始日期到结束时间的日期字符串列表,日期格式为yyyy-MM-dd
*
* @return 日期集合
*/
public List<String> getDates(TimeCycle cycle) {
return getDates(getStart(cycle).timestamp, getEnd(cycle).timestamp);
}
/**
* 获取开始时间戳到结束时间戳的日期字符串列表,日期格式为yyyy-MM-dd
*
* @param startTime 开始时间戳
* @param endTime 结束时间戳
* @return 日期字符串列表
*/
public static List<String> getDates(int startTime, int endTime) {
// 结束时间必须大于开始时间
assert endTime >= startTime;
// 返回的日期集合
List<String> days = new ArrayList<>();
// 获取结束时间当天最后一秒作为结束时间
endTime = Timestamp.of(endTime).getStart(TimeCycle.DAY).timestamp + DAY_SECONDS - 1;
for (int nextDay = startTime; nextDay <= endTime; nextDay = nextDay + DAY_SECONDS) {
days.add(Timestamp.of(nextDay).toDate(TimeFormat.YYYY_MM_DD));
}
return days;
}
/**
* 得到开始日期到结束日期的日期字符串列表,日期格式为yyyy-MM-dd
*
* @param startDate 开始日期,日期格式为yyyy-MM-dd
* @param endDate 结束日期,日期格式为yyyy-MM-dd
* @return 日期字符串列表
*/
public static List<String> getDates(String startDate, String endDate) {
return getDates(ofDate(startDate, TimeFormat.YYYY_MM_DD).timestamp,
ofDate(endDate, TimeFormat.YYYY_MM_DD).timestamp);
}
/**
* 判断当前时间戳是否是指定范围内的
*
* @param startTime 开始时间戳
* @param endTime 结束时间戳
* @return 结果
*/
public static boolean in(int startTime, int endTime) {
int nowTime = Timestamp.of().get();
return nowTime >= startTime && nowTime <= endTime;
}
/**
* 时间戳转LocalDateTime,带china时区
*
* @param t 时间戳
* @return LocalDateTime对象
*/
public static LocalDateTime toLocalDateTime(int t) {
return LocalDateTime.ofEpochSecond(t, 0, LOCAL_ZONE_OFFSET);
}
/**
* 获取LocalDateTime对应的时间戳
*
* @param ldt LocalDateTime对象
* @return 时间戳
*/
public static int toTimestamp(LocalDateTime ldt) {
return (int) ldt.toEpochSecond(LOCAL_ZONE_OFFSET);
}
/**
* 判断传入的开始和结束时间是否在同一天
*
* @param startTime 开始时间戳
* @param endTime 结束时间戳
* @return 结果
*/
public static boolean isSameDay(int startTime, int endTime) {
return endTime - new Timestamp(startTime).getStart(TimeCycle.DAY).timestamp < DAY_SECONDS;
}
/**
* 判断时间是否是否在今天区间内
*
* @param t 任意时间戳
* @return 是否在区间标识
*/
public static boolean isToday(int t) {
int start = getZero(Timestamp.of().get());
int end = start + DAY_SECONDS - 1;
return t >= start && t <= end;
}
/**
* 判断时间是否是否在昨天区间内
*
* @param t 任意时间戳
* @return 是否在区间标识
*/
public static boolean isYesterday(int t) {
return isToday(t + DAY_SECONDS);
}
/**
* 获取unix时间零点对应的unix time
*
* @param unixTime unix time
*/
private static int getZero(int unixTime) {
// 将unix time转换为LocalDateTime
LocalDateTime dt = LocalDateTime.ofEpochSecond(unixTime, 0, LOCAL_ZONE_OFFSET)
.withHour(0).withMinute(0).withSecond(0);
// 转换回unix time
return (int) dt.toEpochSecond(LOCAL_ZONE_OFFSET);
}
}
时间格式枚举:
package com.x7sy.microservice.game.mgmt.volcengine;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import lombok.Getter;
import lombok.ToString;
@SuppressWarnings("all")
@Getter
@ToString
public enum TimeFormat {
YYYY("yyyy"),
YYYY_CHN("yyyy年"),
YYYYMM("yyyyMM"),
YYYY_MM("yyyy-MM"),
YYYYMM_CHN("yyyy年MM月"),
YYYYMMDD("yyyyMMdd"),
YYYY_MM_DD("yyyy-MM-dd"),
YYYY_MM_DD_CHN("yyyy年MM月dd日"),
YYYYMMDDHH("yyyyMMddHH"),
YYYY_MM_DD_HH("yyyy-MM-dd HH"),
YYYY_MM_DD_HH_CHN("yyyy年MM月dd日 HH时"),
YYYYMMDDHHMM("yyyyMMddHHmm"),
YYYY_MM_DD_HH_MM("yyyy-MM-dd HH:mm"),
YYYY_MM_DD_HH_MM_CHN("yyyy年MM月dd日 HH时mm分"),
YYYYMMDDHHMMSS("yyyyMMddHHmmss"),
YYYY_MM_DD_HH_MM_SS("yyyy-MM-dd HH:mm:ss"),
YYYY_MM_DD_HH_MM_SS_CHN("yyyy年MM月dd日 HH时mm分ss秒"),
YYYYMMDDHHMMSSSSS("yyyyMMddHHmmssSSS"),
YYYY_MM_DD_HH_MM_SS_SSS("yyyy-MM-dd HH:mm:ss.SSS"),
YYYY_MM_DD_HH_MM_SS_SSS_CHN("yyyy年MM月dd日 HH时mm分ss秒SSS毫秒");
private final String code;
private final DateTimeFormatter formatter;
TimeFormat(String code) {
this.code = code;
this.formatter = new DateTimeFormatterBuilder().appendPattern(code)
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
}
}
时间类型枚举:
public enum TimeCycle {
/*** 年月周日时分秒*/
YEAR,
MONTH,
WEEK,
DAY,
HOUR,
MINUTE,
SECOND;
}