org.nervousync.utils.DateTimeUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-jdk11 Show documentation
Show all versions of utils-jdk11 Show documentation
Java utility collections, development by Nervousync Studio (NSYC)
/*
* Licensed to the Nervousync Studio (NSYC) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nervousync.utils;
import java.text.DateFormat;
import java.text.ParseException;
import java.time.*;
import java.time.chrono.ChronoZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.nervousync.commons.Globals;
/**
* Date time utilities
* 日期时间工具集
*
* @author Steven Wee [email protected]
* @version $Revision: 1.2.0 $ $Date: Jan 13, 2010 11:15:20 $
*/
public final class DateTimeUtils {
/**
* Static value for date format yyyy/MM/dd
* 日期格式 yyyy/MM/dd 的静态值
*/
public static final String DEFAULT_DATE_PATTERN = "yyyy/MM/dd";
/**
* Static value for date format yyyy-MM-dd'T'HH:mm:ss
* 日期格式 yyyy-MM-dd'T'HH:mm:ss 的静态值
*/
public static final String DEFAULT_DATETIME_PATTERN_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss";
/**
* Static value for date format EEE, dd MMM yyyy HH:mm:ss 'GMT'. Using for generated Response header: Last-Modified
* 日期格式 EEE, dd MMM yyyy HH:mm:ss 'GMT' 的静态值。用于生成的响应头:Last-Modified
*/
public static final String LAST_MODIFIED_DATETIME_PATTERN = "EEE, dd MMM yyyy HH:mm:ss 'GMT'";
/**
* Static value for date format EEE, dd-MMM-yyyy HH:mm:ss 'GMT'
* 日期格式 EEE, dd-MMM-yyyy HH:mm:ss 'GMT' 的静态值
*/
public static final String COOKIE_DATETIME_PATTERN = "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'";
/**
* Static DateTimeFormatter instance for date format yyyy/MM/dd
* 静态DateTimeFormatter实例,使用的日期格式:yyyy/MM/dd
*/
public static final DateTimeFormatter DEFAULT_ISO8601_PATTERN =
DateTimeFormatter.ofPattern(DEFAULT_DATETIME_PATTERN_ISO8601);
/**
* Static DateTimeFormatter instance for the site map date format
* 静态DateTimeFormatter实例,使用SiteMap的日期格式
*/
public static final DateTimeFormatter DEFAULT_SITE_MAP_PATTERN =
DateTimeFormatter.ofPattern(DEFAULT_DATETIME_PATTERN_ISO8601 + DateTimeUtils.getTimeZone());
/**
* Static DateTimeFormatter instance for date format yyyyMMdd
* 静态DateTimeFormatter实例,使用的日期格式:yyyyMMdd
*/
public static final DateTimeFormatter DEFAULT_INT_PATTERN = DateTimeFormatter.ofPattern("yyyyMMdd");
/**
* Static DateTimeFormatter instance for date format HHmmssSSS
* 静态DateTimeFormatter实例,使用的日期格式:HHmmssSSS
*/
public static final DateTimeFormatter DEFAULT_TIME_PATTERN = DateTimeFormatter.ofPattern("HHmmssSSS");
/**
* Static DateTimeFormatter instance for date format yyyyMMddHHmm
* 静态DateTimeFormatter实例,使用的日期格式:yyyyMMddHHmm
*/
public static final DateTimeFormatter DEFAULT_LONG_PATTERN = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
/**
* Current UTC Clock Instance
* 当前UTC时钟实例对象
*
*/
private static final UTCClock UTC_CLOCK = new UTCClock();
/**
* Private constructor for DateTimeUtils
* 日期时间工具集的私有构造方法
*/
private DateTimeUtils() {
}
/**
* Formats given date according to string with ISO8601 format
* 使用ISO8601标准格式化给定的日期实例对象
*
* @param date date instance
* 日期实例对象
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatDateForSiteMap(final Date date) {
if (date == null) {
return Globals.DEFAULT_VALUE_STRING;
}
return formatDate(date, DEFAULT_SITE_MAP_PATTERN);
}
/**
* Parses given string according to java.util.Date
with ISO8601 format
* 使用ISO8601标准解析给定日期字符串为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* If parameter string is null or empty string
* 如果格式化的日期时间字符串为null或者为空字符串
*/
public static Date parseSiteMapDate(final String string) throws ParseException {
return parseDate(string, DEFAULT_DATETIME_PATTERN_ISO8601 + DateTimeUtils.getTimeZone());
}
/**
* Formats current GMT datetime according to string with vCard format
* 使用vCard标准格式化当前的GMT时间
*
* @return formatted date time string and ending character is 'Z'
* 格式化后的日期时间字符串并以字符'Z'结尾
*/
public static String formatGMTDateForVCard() {
return ZonedDateTime.ofInstant(Instant.now(), ZoneId.of("+00:00"))
.format(DateTimeFormatter.ofPattern(DEFAULT_DATETIME_PATTERN_ISO8601 + "'Z'"));
}
/**
* Formats given date according to string with vCard format
* 使用vCard标准格式化给定的日期实例对象
*
* @param date date instance
* 日期实例对象
*
* @return formatted date time string and ending character is 'Z'
* 格式化后的日期时间字符串并以字符'Z'结尾
*/
public static String formatDateForVCard(final Date date) {
if (date == null) {
return null;
}
return formatDate(date, DEFAULT_ISO8601_PATTERN) + "Z";
}
/**
* Parses given GMT date time string according to java.util.Date
* 解析给定的GMT日期字符串为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* If parameter string is null or empty string
* 如果格式化的日期时间字符串为null或者为空字符串
*/
public static Date parseGMTDate(final String string) throws ParseException {
return parseDate(string, COOKIE_DATETIME_PATTERN);
}
/**
* Parses given string according to java.util.Date
using given date time format
* 使用给定的日期时间格式解析给定的日期字符串为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
* @param format date time format
* 日期时间格式
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* If parameter string is null or empty string
* 如果格式化的日期时间字符串为null或者为空字符串
*/
public static Date parseDate(final String string, final String format) throws ParseException {
if (string == null || string.length() == 0) {
throw new ParseException("Date string is null", 0);
}
String datetimeFormat = StringUtils.isEmpty(format) ? DEFAULT_DATE_PATTERN : format;
return Date.from(LocalDate.parse(string, DateTimeFormatter.ofPattern(datetimeFormat))
.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
/**
* Formats given date according to string with last modify format
* 使用Last-Modify标准格式化给定的日期实例对象
*
* @param date date instance
* 日期实例对象
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String lastModified(final Date date) {
return formatDate(date, DateTimeFormatter.ofPattern(LAST_MODIFIED_DATETIME_PATTERN));
}
/**
* Formats given date according to string with last modify format
* 使用Last-Modify标准格式化给定的日期实例对象
*
* @param timeMilliseconds date time milliseconds
* 日期时间的毫秒数
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String lastModified(final long timeMilliseconds) {
return formatDate(new Date(timeMilliseconds), DateTimeFormatter.ofPattern(LAST_MODIFIED_DATETIME_PATTERN));
}
/**
* Formats given date according to string with system format
* 使用系统格式化给定的日期实例对象
*
* @param date date instance
* 日期实例对象
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatDate(final Date date) {
return formatDate(date, DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL));
}
/**
* Formats current date according to int with "yyyyMMdd" format
* 使用"yyyyMMdd"格式化当前日期时间为数字
*
* @return formatted date time int value
* 格式化后的日期时间数字格式
*/
public static int currentDate() {
return Integer.parseInt(LocalDate.now().format(DEFAULT_INT_PATTERN));
}
/**
* Formats current UTC date according to int with "yyyyMMdd" format
* 使用"yyyyMMdd"格式化当前日期时间为数字
*
* @return formatted UTC date time int value
* 格式化后的UTC日期时间数字格式
*/
public static int currentUTCDate() {
return Integer.parseInt(DateTimeUtils.formatDate(new Date(currentUTCTimeMillis()), DEFAULT_INT_PATTERN));
}
/**
* Format and calculate date according to int with "yyyyMMdd" format by given expire time
* 使用"yyyyMMdd"格式化并计算过期日期时间为数字
*
* @param expireTime Expire time milliseconds
* 过期时间的毫秒数
*
* @return formatted and calculated date time int value
* 格式化并计算后的日期时间数字格式
*/
public static int expireDay(final long expireTime) {
return Integer.parseInt(DateTimeUtils.formatDate(new Date(currentTimeMillis() + expireTime),
DEFAULT_INT_PATTERN));
}
/**
* Format and calculate UTC date according to int with "yyyyMMdd" format by given expire time
* 使用"yyyyMMdd"格式化并计算过期UTC日期时间为数字
*
* @param expireTime Expire time milliseconds
* 过期时间的毫秒数
*
* @return formatted and calculated UTC date time int value
* 格式化并计算后的UTC日期时间数字格式
*/
public static int expireUTCDay(long expireTime) {
return Integer.parseInt(DateTimeUtils.formatDate(new Date(currentUTCTimeMillis() + expireTime),
DEFAULT_INT_PATTERN));
}
/**
* Format and calculate date according to int with "yyyyMMdd" format by given month count
* 使用"yyyyMMdd"格式化并计算过期日期时间为数字
*
* @param monthCount Expire month count
* 过期月份计数
*
* @return formatted and calculated date time int value
* 格式化并计算后的日期时间数字格式
*/
public static long expireMonth(int monthCount) {
return currentTimeMillis() + (expireDayCount(monthCount) * 24 * 60 * 60 * 1000L);
}
/**
* Format and calculate UTC date according to int with "yyyyMMdd" format by given month count
* 使用"yyyyMMdd"格式化并计算过期UTC日期时间为数字
*
* @param monthCount Expire month count
* 过期月份计数
*
* @return formatted and calculated UTC date time int value
* 格式化并计算后的UTC日期时间数字格式
*/
public static long expireUTCMonth(int monthCount) {
return currentUTCTimeMillis() + (expireDayCount(monthCount) * 24 * 60 * 60 * 1000L);
}
/**
* Formats current date according to int with "yyyyMMddHHmm" format
* 使用"yyyyMMddHHmm"格式化当前日期时间为数字
*
* @return formatted date time int value
* 格式化后的日期时间数字格式
*/
public static long currentTime() {
return Long.parseLong(formatDate(new Date(currentTimeMillis()), DEFAULT_LONG_PATTERN));
}
/**
* Formats current UTC date according to int with "yyyyMMddHHmm" format
* 使用"yyyyMMddHHmm"格式化当前UTC日期时间为数字
*
* @return formatted date time int value
* 格式化后的日期时间数字格式
*/
public static long currentUTCTime() {
return Long.parseLong(formatDate(new Date(currentUTCTimeMillis()), DEFAULT_LONG_PATTERN));
}
/**
* Read current year number
* 读取当前年份
*
* @return Current Year
* 当前年份
*/
public static int currentYear() {
return Calendar.getInstance().get(Calendar.YEAR);
}
/**
* Read current month number
* 读取当前月份
*
* @return Current month
* 当前月份
*/
public static int currentMonth() {
return Calendar.getInstance().get(Calendar.MONTH) + 1;
}
/**
* Read current day number
* 读取当前日期
*
* @return Current day
* 当前日期
*/
public static int currentDay() {
return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
}
/**
* Read current year hour
* 读取当前小时
*
* @return Current hour
* 当前小时
*/
public static int currentHour() {
return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
}
/**
* Read current year minute
* 读取当前分钟
*
* @return Current minute
* 当前分钟
*/
public static int currentMinute() {
return Calendar.getInstance().get(Calendar.MINUTE);
}
/**
* Calculate days count of given year and month
* 计算给定的年份和月份有多少天
*
* @param year Given year
* 给定的年份
* @param month Given month
* 给定的月份
*
* @return Day count
* 天数
*/
public static int getDaysOfMonth(final int year, final int month) {
Calendar calendar = Calendar.getInstance();
switch (month) {
case 1:
calendar.set(year, Calendar.JANUARY, 1);
break;
case 2:
calendar.set(year, Calendar.FEBRUARY, 1);
break;
case 3:
calendar.set(year, Calendar.MARCH, 1);
break;
case 4:
calendar.set(year, Calendar.APRIL, 1);
break;
case 5:
calendar.set(year, Calendar.MAY, 1);
break;
case 6:
calendar.set(year, Calendar.JUNE, 1);
break;
case 7:
calendar.set(year, Calendar.JULY, 1);
break;
case 8:
calendar.set(year, Calendar.AUGUST, 1);
break;
case 9:
calendar.set(year, Calendar.SEPTEMBER, 1);
break;
case 10:
calendar.set(year, Calendar.OCTOBER, 1);
break;
case 11:
calendar.set(year, Calendar.NOVEMBER, 1);
break;
case 12:
calendar.set(year, Calendar.DECEMBER, 1);
break;
default:
return Globals.DEFAULT_VALUE_INT;
}
return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
}
/**
* Converts input time from Java to DOS format
* 转换给定的Java日期为DOS日期
*
* @param time Given time value
* 给定的时间值
*
* @return time in DOS format
* DOS格式的日期
*/
public static long toDosTime(final long time) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time);
long year = cal.get(Calendar.YEAR);
if (year < 1980) {
return (1 << 21) | (1 << 16);
}
return (year - 1980) << 25
| (cal.get(Calendar.MONTH) + 1) << 21
| cal.get(Calendar.DATE) << 16
| cal.get(Calendar.HOUR_OF_DAY) << 11
| cal.get(Calendar.MINUTE) << 5
| cal.get(Calendar.SECOND) >> 1;
}
/**
* Converts input time from DOS to Java format
* 转换给定的DOS日期为Java日期
*
* @param dosTime Given time value
* 给定的时间值
*
* @return time in Java format
* Java格式的日期
*/
public static long dosToJavaTime(final long dosTime) {
int month;
switch ((int)((dosTime >> 21) & 0x0F)) {
case 1:
month = Calendar.JANUARY;
break;
case 2:
month = Calendar.FEBRUARY;
break;
case 3:
month = Calendar.MARCH;
break;
case 4:
month = Calendar.APRIL;
break;
case 5:
month = Calendar.MAY;
break;
case 6:
month = Calendar.JUNE;
break;
case 7:
month = Calendar.JULY;
break;
case 8:
month = Calendar.AUGUST;
break;
case 9:
month = Calendar.SEPTEMBER;
break;
case 10:
month = Calendar.OCTOBER;
break;
case 11:
month = Calendar.NOVEMBER;
break;
case 12:
month = Calendar.DECEMBER;
break;
default:
return Globals.DEFAULT_VALUE_LONG;
}
Calendar calendar = Calendar.getInstance();
calendar.set((int)(((dosTime >> 25) & 0x7F) + 1980), month,
(int)((dosTime >> 16) & 0x1F),
(int)((dosTime >> 11) & 0x1F),
(int)((dosTime >> 5) & 0x3F),
(int)((dosTime << 1) & 0x3E));
calendar.clear(Calendar.MILLISECOND);
return calendar.getTimeInMillis();
}
/**
* Retrieve current time in milliseconds.
* 读取当前时间与1970-01-01差值的毫秒数
*
* @return Read value
* 读取的值
*/
public static long currentTimeMillis() {
return UTC_CLOCK.currentTimeMillis();
}
/**
* Retrieve current UTC time in milliseconds.
* 读取当前UTC时间与1970-01-01差值的毫秒数
*
* @return Read value
* 读取的值
*/
public static long currentUTCTimeMillis() {
return UTC_CLOCK.currentUTCTimeMillis();
}
/**
* Formats given date according to string with given DateTimeFormatter instance
* 使用给定的日期时间格式化实例对象将给定的日期实例对象转换为字符串
*
* @param date date instance
* 日期实例对象
* @param dateTimeFormatter DateTimeFormatter instance
* 日期时间格式化实例对象
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatDate(final Date date, final DateTimeFormatter dateTimeFormatter) {
return DateTimeUtils.formatDate(date, dateTimeFormatter, TimeZone.getDefault());
}
/**
* Formats given date according and time zone to string with given DateTimeFormatter instance
* 使用给定的日期时间格式化实例对象和时区将给定的日期实例对象转换为字符串
*
* @param date date instance
* 日期实例对象
* @param dateTimeFormatter DateTimeFormatter instance
* 日期时间格式化实例对象
* @param timeZone Timezone instance
* 时区实例对象
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatDate(final Date date, final DateTimeFormatter dateTimeFormatter,
final TimeZone timeZone) {
Date useDate = (date == null) ? new Date() : date;
return useDate.toInstant().atZone(timeZone.toZoneId()).toLocalDateTime()
.format(dateTimeFormatter);
}
/**
* Formats given date according to string with given locale instance and date style code
* 使用给定的地区实例对象和日期风格代码将给定的日期实例对象转换为字符串
*
* @param date date instance
* 日期实例对象
* @param locale locale instance
* 地区实例对象
* @param dateStyle date style code
* 日期风格代码
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatDate(final Date date, final Locale locale, final int dateStyle) {
return DateFormat.getDateInstance(dateStyle, locale).format(date);
}
/**
* Formats given date according to string with given locale instance using date style DateFormat.MEDIUM
* 使用给定的地区实例对象和日期风格代码DateFormat.MEDIUM
将给定的日期实例对象转换为字符串
*
* @param date date instance
* 日期实例对象
* @param locale locale instance
* 地区实例对象
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatDate(final Date date, final Locale locale) {
return formatDate(date, locale, DateFormat.MEDIUM);
}
/**
* Parse given string according to date with given locale instance and date style code
* 使用给定的地区实例对象和日期风格代码将给定的字符串转换为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
* @param locale locale instance
* 地区实例对象
* @param dateStyle date style code
* 日期风格代码
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* if given string could not be properly parsed according to given locale and style
* 如果给定的字符串无法根据给定的区域设置和样式正确解析
*/
public static Date parseDate(final String string, final Locale locale, final int dateStyle) throws ParseException {
return DateFormat.getDateInstance(dateStyle, locale).parse(string);
}
/**
* Parse given string according to date with given locale instance and date style DateFormat.MEDIUM
* 使用给定的地区实例对象和日期风格DateFormat.MEDIUM
将给定的字符串转换为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
* @param locale locale instance
* 地区实例对象
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* if given string could not be properly parsed according to given locale and style
* 如果给定的字符串无法根据给定的区域设置和样式正确解析
*/
public static Date parseDate(final String string, final Locale locale) throws ParseException {
return parseDate(string, locale, DateFormat.MEDIUM);
}
/**
* Formats given date according to string with given locale instance and time style code
* 使用给定的地区实例对象和时间风格代码将给定的日期实例对象转换为字符串
*
* @param time date instance
* 日期实例对象
* @param locale locale instance
* 地区实例对象
* @param timeStyle time style code
* 时间风格代码
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatTime(final Date time, final Locale locale, final int timeStyle) {
DateFormat formatter = DateFormat.getTimeInstance(timeStyle, locale);
return formatter.format(time);
}
/**
* Formats given date according to string with given locale instance using time style DateFormat.MEDIUM
* 使用给定的地区实例对象和时间风格代码DateFormat.MEDIUM
将给定的日期实例对象转换为字符串
*
* @param time date instance
* 日期实例对象
* @param locale locale instance
* 地区实例对象
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatTime(final Date time, final Locale locale) {
return formatTime(time, locale, DateFormat.MEDIUM);
}
/**
* Parse given string according to date with given locale instance and time style code
* 使用给定的地区实例对象和日期风格代码将给定的字符串转换为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
* @param locale locale instance
* 地区实例对象
* @param timeStyle time style code
* 时间风格代码
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* if given string could not be properly parsed according to given locale and style
* 如果给定的字符串无法根据给定的区域设置和样式正确解析
*/
public static Date parseTime(final String string, final Locale locale, final int timeStyle) throws ParseException {
return DateFormat.getTimeInstance(timeStyle, locale).parse(string);
}
/**
* Parse given string according to date with given locale instance and time style DateFormat.MEDIUM
* 使用给定的地区实例对象和时间风格DateFormat.MEDIUM
将给定的字符串转换为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
* @param locale locale instance
* 地区实例对象
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* if given string could not be properly parsed according to given locale and style
* 如果给定的字符串无法根据给定的区域设置和样式正确解析
*/
public static Date parseTime(final String string, final Locale locale) throws ParseException {
return parseTime(string, locale, DateFormat.MEDIUM);
}
/**
* Formats given date according to string with given locale instance, date style code and time style code
* 使用给定的地区实例对象、日期风格代码和时间风格代码将给定的日期实例对象转换为字符串
*
* @param date date instance
* 日期实例对象
* @param locale locale instance
* 地区实例对象
* @param dateStyle date style code
* 日期风格代码
* @param timeStyle time style code
* 时间风格代码
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatDateTime(final Date date, final Locale locale, final int dateStyle, final int timeStyle) {
return DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale).format(date);
}
/**
* Formats given date according to string with given locale instance using date style DateFormat.MEDIUM
* 使用给定的地区实例对象和日期、时间风格代码DateFormat.MEDIUM
将给定的日期实例对象转换为字符串
*
* @param date date instance
* 日期实例对象
* @param locale locale instance
* 地区实例对象
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatDateTime(final Date date, final Locale locale) {
return formatDateTime(date, locale, DateFormat.MEDIUM, DateFormat.MEDIUM);
}
/**
* Formats given date according to string with system locale instance using date style DateFormat.MEDIUM
* 使用系统地区实例对象和日期、时间风格代码DateFormat.MEDIUM
将给定的日期实例对象转换为字符串
*
* @param date date instance
* 日期实例对象
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String formatDateTime(final Date date) {
return formatDateTime(date, Globals.DEFAULT_LOCALE);
}
/**
* Parse given string according to date with given locale instance, date style code and time style code
* 使用给定的地区实例对象、日期风格代码和时间风格代码将给定的字符串转换为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
* @param locale locale instance
* 地区实例对象
* @param dateStyle date style code
* 日期风格代码
* @param timeStyle time style code
* 时间风格代码
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* if given string could not be properly parsed according to given locale and style
* 如果给定的字符串无法根据给定的区域设置和样式正确解析
*/
public static Date parseDateTime(final String string, final Locale locale, final int dateStyle, final int timeStyle)
throws ParseException {
return DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale).parse(string);
}
/**
* Parse given string according to date with given locale instance, date style and time style using DateFormat.MEDIUM
* 使用给定的地区实例对象和日期时间风格DateFormat.MEDIUM
将给定的字符串转换为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
* @param locale locale instance
* 地区实例对象
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* if given string could not be properly parsed according to given locale and style
* 如果给定的字符串无法根据给定的区域设置和样式正确解析
*/
public static Date parseDateTime(final String string, final Locale locale) throws ParseException {
return parseDateTime(string, locale, DateFormat.MEDIUM, DateFormat.MEDIUM);
}
/**
* Parse given string according to date with system locale instance, date style and time style using DateFormat.MEDIUM
* 使用系统地区实例对象和日期时间风格DateFormat.MEDIUM
将给定的字符串转换为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
*
* @return date instance
* 日期实例对象
*
* @throws ParseException
* if given string could not be properly parsed according to given locale and style
* 如果给定的字符串无法根据给定的区域设置和样式正确解析
*/
public static Date parseDateTime(final String string) throws ParseException {
return parseDateTime(string, Globals.DEFAULT_LOCALE);
}
/**
* Formats given date according to string with given locale instance and date pattern string
* 使用给定的地区实例对象和格式代码将给定的日期实例对象转换为字符串
*
* @param date date instance
* 日期实例对象
* @param locale locale instance
* 地区实例对象
* @param pattern Pattern string
* 格式字符串
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String format(final Date date, final Locale locale, final String pattern) {
return Optional.ofNullable(date)
.map(Date::toInstant)
.map(instant -> instant.atZone(ZoneId.systemDefault()))
.map(ZonedDateTime::toLocalDateTime)
.map(localDateTime -> localDateTime.format(DateTimeFormatter.ofPattern(pattern, locale)))
.orElse(LocalDateTime.now().format(DateTimeFormatter.ofPattern(pattern, locale)));
}
/**
* Parse given string according to date with given locale instance and date pattern string
* 使用给定的地区实例对象和格式代码将给定的字符串转换为日期实例对象
*
* @param string formatted date time string
* 格式化的日期时间字符串
* @param locale locale instance
* 地区实例对象
* @param pattern Pattern string
* 格式字符串
*
* @return date instance
* 日期实例对象
*
* @throws DateTimeParseException
* if given string could not be properly parsed according to given pattern string
* 如果给定的字符串无法根据给定的格式字符串正确解析
*/
public static Date parse(final String string, final Locale locale, final String pattern)
throws DateTimeParseException {
if (StringUtils.isEmpty(string)) {
return null;
}
return Optional.of(LocalDateTime.parse(string, DateTimeFormatter.ofPattern(pattern, locale)))
.map(localDateTime -> localDateTime.atZone(ZoneId.systemDefault()))
.map(ChronoZonedDateTime::toInstant)
.map(Date::from)
.orElse(null);
}
/**
* Check current year is leap year
* 检查当前年份是否为闰年
*
* @return check result
* 检查结果
*/
public static boolean isLeapYear() {
return LocalDate.now().isLeapYear();
}
/**
* Check given year is leap year
* 检查给定的年份是否为闰年
*
* @param year which year will check
* 将要检查的年份
*
* @return check result
* 检查结果
*/
public static boolean isLeapYear(final int year) {
return (year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0));
}
/**
* Retrieve first day of current month and format to string using given pattern
* 读取当前月份的第一天并使用给定的格式字符串将日期转换为格式化的字符串
*
* @param pattern Pattern string
* 格式字符串
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String getCurrentMonthFirstDay(final String pattern) {
return LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth())
.format(DateTimeFormatter.ofPattern(pattern));
}
/**
* Retrieve last day of current month and format to string using given pattern
* 读取当前月份的最后一天并使用给定的格式字符串将日期转换为格式化的字符串
*
* @param pattern Pattern string
* 格式字符串
*
* @return formatted date time string
* 格式化后的日期时间字符串
*/
public static String getCurrentMonthLastDay(final String pattern) {
return LocalDateTime.now().with(TemporalAdjusters.lastDayOfMonth())
.format(DateTimeFormatter.ofPattern(pattern));
}
/**
* Calculate days count of given month count from current day
* 根据给定的月数计算当前日期往后月数有多少天
*
* @param monthCount Expire month count
* 过期月份计数
*
* @return Calculated day count
* 计算的天数结果
*/
private static int expireDayCount(int monthCount) {
int dayCount = Globals.INITIALIZE_INT_VALUE;
int currentYear = currentYear();
int currentMonth = currentMonth();
for (int i = 0 ; i < monthCount ; i++) {
dayCount += getDaysOfMonth(currentYear, currentMonth);
currentMonth++;
}
return dayCount;
}
/**
* Get default time zone string
* 读取默认的时区并转换为字符串
*
* @return formatted time zone string
* 格式化后的时区字符串
*/
private static String getTimeZone() {
StringBuilder stringBuilder = new StringBuilder();
int zoneCode = TimeZone.getDefault().getRawOffset() / (1000 * 60 * 60);
stringBuilder.append(zoneCode >= 0 ? "+" : "-");
if (zoneCode < 0) {
zoneCode = Math.abs(zoneCode);
}
stringBuilder.append(zoneCode < 10 ? "0" : "").append(zoneCode).append(":00");
return stringBuilder.toString();
}
/**
* UTC Clock
* UTC时钟
*
* @author Steven Wee [email protected]
* @version $Revision: 1.0.0 $ $Date: Jan 13, 2010 11:46:19 $
*/
private static final class UTCClock {
/**
* Current local time milliseconds
* 当前本地时间的毫秒数
*/
private final AtomicLong currentLocalTime = new AtomicLong(System.currentTimeMillis());
/**
* Current UTC time milliseconds
* 当前UTC时间的毫秒数
*/
private final AtomicLong currentUTCTime =
new AtomicLong(System.currentTimeMillis() - TimeZone.getDefault().getRawOffset());
/**
* Constructor method for UTC clock
* UTC时钟的构造方法
*/
public UTCClock() {
ScheduledThreadPoolExecutor threadPoolExecutor =
new ScheduledThreadPoolExecutor(1, r -> {
Thread thread = new Thread(r);
thread.setDaemon(Boolean.TRUE);
return thread;
});
threadPoolExecutor.scheduleAtFixedRate(this::readTime, 0L, 1L, TimeUnit.MILLISECONDS);
}
/**
* Read current local time milliseconds
* 读取当前本地时间的毫秒数
*
* @return Current local time milliseconds
* 当前本地时间的毫秒数
*/
public long currentTimeMillis() {
return this.currentLocalTime.get();
}
/**
* Read current UTC time milliseconds
* 读取当前UTC时间的毫秒数
*
* @return Current UTC time milliseconds
* 当前UTC时间的毫秒数
*/
public long currentUTCTimeMillis() {
return this.currentUTCTime.get();
}
/**
* Schedule method for read current local time and UTC time
* 调度方法用于读取当前本地时间和UTC时间
*/
private void readTime() {
long currentTime = System.currentTimeMillis();
this.currentLocalTime.set(currentTime);
this.currentUTCTime.set(currentTime - TimeZone.getDefault().getRawOffset());
}
}
}