目录
一、获取当前时间(系统时间)距离特定时间(如18:00:00)的间隔
六、将 unix 时间戳转换为特定格式的日期数组,其中索引位置0为日期, 索引位置1为时间
十一、将 Instant 时间转为形如 2022102714 的时间
十三、将LocalDate 转换为 特定格式的 字符串格式的日期
十六、将LocalTime 转换为 特定格式的 字符串格式的时间
时间是计算机程序中常用的数据类型之一,它在很多场景中都有着重要的作用,如日志记录、计时、缓存、定时任务等等。因此开发一个实用、可靠的时间工具类对于程序员来说是非常有必要的。
一个好的时间工具类应该具备以下特点:易用性高、精度高、能够处理各种时间格式、支持不同的时区、提供丰富的时间计算方法等。在本文中,我们将探讨如何设计一个高质量的时间工具类。
一、获取当前时间(系统时间)距离特定时间(如18:00:00)的间隔
/**
* 获取当前时间(系统时间)距离特定时间(如18:00:00)的间隔,结果可能为正,亦可为负
* 间隔 >=0: 表示当前时间未到达(或刚好到达)设定的时间(含异常情况)
* 间隔 <0: 表示当前时间已超过设定的时间
*
* @param time 字符串形式的时间,如18:00:00
* @return long
*/
public static long getTimeDiffWithMills(String time) {
DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
DateFormat dayFormat = new SimpleDateFormat("yy-MM-dd");
try {
Date curDate = dateFormat.parse(dayFormat.format(new Date()) + " " + time);
return curDate.getTime() - System.currentTimeMillis();
} catch (ParseException e) {
LOGGER.error("时间转换出错,原因是 <{}>", e.getMessage());
return 0;
}
}
二、将 unix 时间戳转换为 相应时区时间
/**
* 将 unix 时间戳转换为 相应时区时间
*
* @param instant Instant
* @param zoneIdType SystemEnumEntity.ZoneIdType
* @return String
*/
public static String instantToString(Instant instant, SystemEnumEntity.ZoneIdType zoneIdType) {
if (null == instant || null == zoneIdType) {
return ConstantUtil.SPECIAL_CHARACTER_EMPTY;
}
try {
return DateTimeFormatter.ofPattern(ConstantUtil.DATE_TIME_FORMAT_GENERAL)
.withZone(ZoneId.of(zoneIdType.getLabel())).format(instant);
} catch (Exception e) {
LOGGER.error("error message: 时间转换异常,原因是 <{}>", e.toString());
return ConstantUtil.SPECIAL_CHARACTER_EMPTY;
}
}
三、将特定时区的字符串时间转换为UTC时间
/**
* 将特定时区的字符串时间转换为UTC时间
*
* @param dateTime String
* @param dateTimeFormat String
* @param zoneIdType SystemEnumEntity.ZoneIdType
* @return Instant
*/
public static Instant stringToInstant(String dateTime, String dateTimeFormat, SystemEnumEntity.ZoneIdType zoneIdType) {
if (StringUtil.isEmpty(dateTime) || StringUtil.isEmpty(dateTimeFormat)) {
LOGGER.error("error message: 待处理的时间无效,请检查,默认返回系统当前的UTC时间");
return Instant.now();
}
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(dateTimeFormat);
LocalDateTime localDateTime = LocalDateTime.parse(dateTime, dateTimeFormatter);
return localDateTime.atZone(ZoneId.of(zoneIdType.getLabel())).toInstant();
} catch (Exception e) {
LOGGER.error("error message: 时间转换异常,原因是 <{}>", e.toString());
return Instant.now();
}
}
四、将原始格式的时间转换为指定格式的时间
/**
* 将原始格式的时间转换为指定格式的时间
*
* @param dateTime String 待转换的时间
* @param initialFormat String 原始格式
* @param convertedFormat String 指定格式
* @return String 发生异常时,使用当前系统时间进行转换
*/
public static String formatDateTime(String dateTime, String initialFormat, String convertedFormat) {
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(initialFormat);
LocalDateTime localDateTime = LocalDateTime.parse(dateTime, dateTimeFormatter);
dateTimeFormatter = DateTimeFormatter.ofPattern(convertedFormat);
return localDateTime.format(dateTimeFormatter);
}
// 转换异常
catch (Exception e) {
LOGGER.error("error message: 时间 <{}> 由格式 <{}> 转为 格式 <{}> 时发生异常,原因是 <{}>", dateTime, initialFormat, convertedFormat, e.toString());
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(convertedFormat));
}
}
五、将 Long 型时间转换为 指定格式的时间
/**
* 将 Long 型时间转换为 指定格式的时间
*
* @param timeStamp String Long型时间
* @param format String 指定格式
* @param zoneIdType SystemEnumEntity.ZoneIdType 时区类型
* @return String 发生异常时,使用当前系统时间进行转换
*/
public static String conversionTime(String timeStamp, String format, SystemEnumEntity.ZoneIdType zoneIdType) {
try {
long times = Long.parseLong(timeStamp) * 1000L;
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(times), ZoneId.of(zoneIdType.getLabel()));
return dateTimeFormatter.format(localDateTime);
}
// 转换异常
catch (Exception e) {
LOGGER.error("error message: Long型时间 <{}> 转为 格式 <{}> 时发生异常,原因是 <{}>", timeStamp, format, e.toString());
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));
}
}
六、将 unix 时间戳转换为特定格式的日期数组,其中索引位置0为日期, 索引位置1为时间
/**
* 将 unix 时间戳转换为特定格式的日期数组,其中索引位置0为日期, 索引位置1为时间
*
* @param timeStamp String long型时间
* @param format String 特定格式
* @return String[] 索引位置0为日期, 索引位置1为时间
*/
public static String[] getDateTimeArrayFromUtc(String timeStamp, String format, SystemEnumEntity.ZoneIdType zoneIdType) {
try {
String time = conversionTime(timeStamp, format, zoneIdType);
return StringUtil.spiltBySpecialCharacter(time, ConstantUtil.SPECIAL_CHARACTER_BACKSPACE);
} catch (Exception e) {
LOGGER.error("error message: Long型时间 <{}> 转为 数组格式时间发生异常,原因是 <{}>", timeStamp, e.toString());
return new String[0];
}
}
七、获取当前日期的特定格式
特定格式:yyyy-MM-dd、yyyy-MM-dd HH:mm:ss、等等
/**
* 获取当前日期的特定格式
*
* @param timeFormat String 日期格式
* @return String
* @throws BusinessException 异常
*/
public static String getCurrentDate(String timeFormat) throws BusinessException {
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(timeFormat);
return dateTimeFormatter.format(LocalDateTime.now());
} catch (Exception e) {
LOGGER.error("error message: 获取当前日期的特定格式,数据异常,原因:<{}>", String.valueOf(e));
throw new BusinessException((SystemErrorCode.DATE_CONVERT_FAILED));
}
}
八、获取从今天起的未来若干个间隔的日期信息
/**
* 获取从今天起的未来若干个间隔的日期信息
*
* @param intervals int
* @return List<String>,形如 2022-06-24, 2022-06-25 ...
*/
public static List<String> getFutureDays(int intervals) {
List<String> futureDaysList = new ArrayList<>();
for (int i = 0; i <= intervals; i++) {
String date = getFutureDate(i, ConstantUtil.DATE_TIME_FORMAT_GENERAL_WITHOUT_HOUR_THREE);
if (StringUtil.isEmpty(date)) {
continue;
}
futureDaysList.add(date);
}
return futureDaysList;
}
九、获取距离当前日期特定间隔特定格式的日期信息
/**
* 获取距离当前日期特定间隔特定格式的日期信息
*
* @param future int 特定间隔
* @param format String 特定格式
* @return String 发生异常时返回空字符串
*/
public static String getFutureDate(int future, String format) {
LocalDate localDate = LocalDate.now().plusDays(future);
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
return dateTimeFormatter.format(localDate);
} catch (Exception e) {
LOGGER.error("error message: 获取距离当前日期第 <{}> 日的日期失败,原因是 <{}>", future, e.toString());
return ConstantUtil.SPECIAL_CHARACTER_EMPTY;
}
}
十、将 String 时间转换为 相应时区下的时间戳
/**
* 将 String 时间转换为 相应时区下的时间戳
*
* @param dateTime String
* @param zoneIdType SystemEnumEntity.ZoneIdType
* @param dateTimeFormatFlag boolean
* True-Instant格式的字符串,形如"2021-11-25T14:00:13Z"
* False-非Instant格式的字符串,形如"2021-11-25 14:00:13"
* @return Instant
* @throws BusinessException 抛出异常
*/
public static Instant stringToInstant(String dateTime,
SystemEnumEntity.ZoneIdType zoneIdType,
boolean dateTimeFormatFlag) throws BusinessException {
if (StringUtil.isEmpty(dateTime) || null == zoneIdType) {
LOGGER.error("error message: 日期时间 <{}> 或 时区信息 <{}> 无效", dateTime, zoneIdType);
throw new BusinessException(GuiErrorCode.ACCESS_PARAMETER_INVALID);
}
try {
if (dateTimeFormatFlag) {
return LocalDateTime.ofInstant(Instant.parse(dateTime), ZoneId.of(zoneIdType.getLabel())).toInstant(ZoneOffset.UTC);
} else {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(ConstantUtil.DATE_TIME_FORMAT_GENERAL);
LocalDateTime localDateTime = LocalDateTime.parse(dateTime, dateTimeFormatter);
return localDateTime.atZone(ZoneId.of(zoneIdType.getLabel())).toInstant();
}
} catch (Exception e) {
LOGGER.error("error message: 字符串格式时间 <{}> 转换为 Instant 异常,原因是 <{}>", dateTime, String.valueOf(e));
throw new BusinessException(SystemErrorCode.DATE_CONVERT_FAILED);
}
}
十一、将 Instant 时间转为形如 2022102714 的时间
/**
* 将 Instant 时间转为形如 2022102714 的时间
*
* @param instant instant Instant 时间
* @return String
*/
public static String convertInstantToDateHour(Instant instant) {
try {
return instant.atOffset(ZoneOffset.ofHours(0)).format(DateTimeFormatter.ofPattern(ConstantUtil.TIME_FORMAT_YEAR_MONTH_DAY_HOUR_FULL_NORMAL));
} catch (Exception e) {
return Instant.now().atOffset(ZoneOffset.ofHours(0)).format(DateTimeFormatter.ofPattern(ConstantUtil.TIME_FORMAT_YEAR_MONTH_DAY_HOUR_FULL_NORMAL));
}
}
十二、将特定格式的字符串日期转为日期形式
/**
* 将特定格式的字符串日期转为日期形式
*
* @param str Date
* @param dateFormat String
* @return String
* @throws BusinessException 自定义异常
*/
public static LocalDate stringToLocalDate(String str, String dateFormat) throws BusinessException {
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(dateFormat);
return LocalDate.parse(str, dateTimeFormatter);
} catch (Exception e) {
LOGGER.error("error message: String 格式日期 <{}> 转换为 LocalDate 格式 <{}> 日期时间异常,原因是:", str, dateFormat, e);
throw new BusinessException(SystemErrorCode.DATE_CONVERT_FAILED);
}
}
十三、将LocalDate 转换为 特定格式的 字符串格式的日期
/**
* 将LocalDate 转换为 特定格式的 字符串格式的日期
*
* @param localDate LocalDate
* @param timeFormat String 特定格式
* @return LocalDate
* @throws BusinessException 自定义异常
*/
public static String localDateToString(LocalDate localDate, String timeFormat) throws BusinessException {
if (null == localDate || StringUtil.isEmpty(timeFormat)) {
throw new BusinessException(GuiErrorCode.ACCESS_PARAMETER_INVALID);
}
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(timeFormat);
return localDate.format(dateTimeFormatter);
} catch (Exception e) {
LOGGER.error("error message: LocalDate<{}> 转换为 <{}> 格式的 字符串格式日期 异常,原因是:", localDate, timeFormat, e);
throw new BusinessException(SystemErrorCode.DATE_CONVERT_FAILED);
}
}
十四、LocalDateTime 转 string
/**
* LocalDateTime 转 string
*
* @param dateDate LocalDateTime
* @param timeFormat String
* @return String
*/
public static String localDataTimeToStringDateTime(LocalDateTime dateDate, String timeFormat) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(timeFormat);
return dateDate.format(dateTimeFormatter);
}
十五、判断日期时间是否有效
/**
* 日期时间 年, 月, 日, 时, 分, 秒, 毫秒 域
*/
private static final List<ChronoField> DATE_TIME_FIELD_LIST = List.of(ChronoField.YEAR,
ChronoField.MONTH_OF_YEAR,
ChronoField.DAY_OF_MONTH,
ChronoField.HOUR_OF_DAY,
ChronoField.MINUTE_OF_HOUR,
ChronoField.SECOND_OF_MINUTE,
ChronoField.MILLI_OF_SECOND);
/**
* 判断日期时间是否有效
*
* @param strDateTime String 日期时间 如 2022-12-01 17:26:17, 2022-12-01, 17:53:24, 17:37
* @param dateTimeFormat String 时间格式 如 yyyy-MM-dd HH:mm:ss, yyyy-MM-dd, HH:mm:ss, HH:mm
* @return boolean True-日期时间有效 False-日期时间无效
*/
public static boolean isDateTimeValid(String strDateTime, String dateTimeFormat) {
try {
if (StringUtil.isEmpty(strDateTime)
|| StringUtil.isEmpty(dateTimeFormat)) {
return false;
}
// // 使用了 uuuu 而不是 yyyy 即 YEAR而不是 YEAR_OF_ERA, 从而避免 将 2022-02-30 这样无效的日期 自动更正为一个有效日期
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(dateTimeFormat.replaceAll("[yY]", "u"))
.withResolverStyle(ResolverStyle.STRICT);
final TemporalAccessor dateTimeFieldAccessor = dateTimeFormatter.parse(strDateTime);
// 日期时间仅有 年, 月, 日, 时, 分, 秒, 毫秒时,校验是否在有效范围内
return DATE_TIME_FIELD_LIST
.stream()
.filter(dateTimeFieldAccessor::isSupported)
.allMatch(field -> field.range().isValidValue(dateTimeFieldAccessor.get(field)));
} catch (Exception e) {
return false;
}
}
十六、将LocalTime 转换为 特定格式的 字符串格式的时间
/**
* 将LocalTime 转换为 特定格式的 字符串格式的时间
*
* @param localTime LocalTime
* @param timeFormat String 特定格式
* @return LocalDate
* @throws BusinessException 自定义异常
*/
public static String localTimeToString(LocalTime localTime, String timeFormat) throws BusinessException {
if (null == localTime || StringUtil.isEmpty(timeFormat)) {
throw new BusinessException(GuiErrorCode.ACCESS_PARAMETER_INVALID);
}
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(timeFormat);
return localTime.format(dateTimeFormatter);
} catch (Exception e) {
LOGGER.error("error message: LocalDate<{}> 转换为 <{}> 格式的 字符串格式时间 异常,原因是:", localTime, timeFormat, e);
throw new BusinessException(SystemErrorCode.DATE_CONVERT_FAILED);
}
}
结尾:
以上这十几种、时间类型转换的方法、有用不了的地方、评论或私信都可、欢迎一起来讨论一下........