日常开发中,我们经常需要使用时间相关类,想必大家对
SimpleDateFormat
并不陌生。主要用它进行时间的格式化输出和解析,挺方便快捷的,但是SimpleDateFormat
并不是一个线程安全的类。在多线程情况下,会出现异常,想必有经验的小伙伴也遇到过。
接下来看看《阿里巴巴开发手册》对SimpleDateFormat
是怎么看待的?
【强制】SimpleDateFormat是线程不安全的类,一般不要定义位static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。
正例:注意线程安全,使用DateUtils。亦推荐如下处理
private static final ThreadLocal df = new ThreadLocal(){
@Override
protected DateFormat initialValue(){
return new SimpleDateFormat("yyyy-MM-dd");
}
};
说明:如果是JDK8的应用,可以使用Instant代替Date,LocalDateTime代替Calendar,DateTimeFormatter 代替SimpleDateFormat,官方给出解释:simple beautiful strong immutable thread-safe
个人总结:
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
/**
* @ClassName DateUtils
* @Description 时间工具类 1.8版本
* @Author QiMing
* @Date 2019/4/30 8:45
* @Version 1.0
*/
public class DateUtils {
/**
* 缺省的日期显示格式: yyyy-MM-dd
*/
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
/**
* 用做单号
*/
public static final String DEFAULT_DATE_FORMAT_ORDER = "yyyyMMdd";
/**
* 缺省的日期显示格式: yyyy-MM
*/
public static final String DEFAULT_YYMM_FORMAT = "yyyy-MM";
/**
* 缺省的日期时间显示格式:yyyy-MM-dd HH:mm:ss
*/
public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
* 缺省的日期时间显示格式:yyyy-MM-dd HH:mm:ss:sss
*/
public static final String YMDHMSS = "yyyy-MM-dd HH:mm:ss:sss";
/**
* 字符串时间
*/
public static final String YMDHMS = "yyyyMMddHHmmss";
/**
* 当前时间
*/
public static Date DATE_NOW = new Date();
/**
* 当前时间
*/
public static LocalDate localDate = LocalDate.now();
/**
* @Title getDay
* @Description 获取年月日(当天)
* @Param []
* @Return java.lang.String
* @Date 2019/6/4 15:26
* @Author QiMing
*/
public static String getDay() {
LocalDate date = LocalDate.now();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT);
return date.format(fmt);
}
/**
* @Title getDayTime
* @Description 年月日时分秒 (当天) 此方法不支持毫秒
* @Param []
* @Return java.lang.String
* @Date 2019/6/4 15:28
* @Author QiMing
*/
public static String getDayTime() {
LocalDateTime date = LocalDateTime.now();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMAT);
return date.format(fmt);
}
/**
* @Title getDateToString
* @Description date类型转换字符串
* @Param [date]
* @Return java.lang.String
* @Date 2019/7/8 11:07
* @Author QiMing
*/
public static String getDateToString(Date date) {
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT_ORDER);
return localDateTime.format(fmt);
}
/**
* @Title getLocalDateToString
* @Description LocalDate转换String
* @Param [localDate]
* @Return java.lang.String
* @Date 2019/7/8 11:10
* @Author QiMing
*/
public static String getLocalDateToString(LocalDate localDate) {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT_ORDER);
return localDate.format(fmt);
}
/**
* @Title getFixedTime
* @Description 自定固定时间
* @Param [year, month, day, hour, minute, second]
* @Return java.time.LocalDateTime
* @Date 2019/7/8 15:23
* @Author QiMing
*/
public static LocalDateTime getFixedTime(int year, int month, int day, int hour, int minute, int second) {
return LocalDateTime.of(year, month, day, hour, minute, second);
}
/**
* @Title settingsTime
* @Description 设置固定时间
* @Param [year, month, day, hour, minute, second]
* @Return java.time.LocalDateTime
* @Date 2019/7/8 15:29
* @Author QiMing
*/
public static LocalDateTime settingsTime(int year, int month, int day, int hour, int minute, int second) {
return LocalDateTime.now().withYear(year).withMonth(month).withDayOfMonth(day).withHour(hour).withMinute(minute).withSecond(second);
}
/**
* @Title firstToMonth
* @Description 当月第一天
* @Param []
* @Return java.time.LocalDate
* @Date 2019/7/8 15:31
* @Author QiMing
*/
public static LocalDate firstToMonth() {
return localDate.with(TemporalAdjusters.firstDayOfMonth());
}
/**
* @Title lastToMonth
* @Description 本月最后一天
* @Param []
* @Return java.time.LocalDate
* @Date 2019/7/8 15:33
* @Author QiMing
*/
public static LocalDate lastToMonth() {
return localDate.with(TemporalAdjusters.lastDayOfMonth());
}
/**
* @Title firstNextMonth
* @Description 下个月第一天
* @Param []
* @Return java.time.LocalDate
* @Date 2019/7/8 15:35
* @Author QiMing
*/
public static LocalDate firstNextMonth() {
return localDate.with(TemporalAdjusters.firstDayOfNextMonth());
}
/**
* @Title firstToYear
* @Description 本年第一天
* @Param []
* @Return java.time.LocalDate
* @Date 2019/7/8 15:36
* @Author QiMing
*/
public static LocalDate firstToYear() {
return localDate.with(TemporalAdjusters.firstDayOfYear());
}
/**
* @Title lastToYear
* @Description 本年最后一天
* @Param []
* @Return java.time.LocalDate
* @Date 2019/7/8 15:37
* @Author QiMing
*/
public static LocalDate lastToYear() {
return localDate.with(TemporalAdjusters.lastDayOfYear());
}
/*——————————————————— 时间相差 start ———————————————————————*/
/**
* @Title difference
* @Description 相差分钟
* @Param [localTime, localTime1]
* @Return long
* @Date 2019/7/8 15:43
* @Author QiMing
*/
public static long difference(LocalTime localTime, LocalTime localTime1) {
return Duration.between(localTime, localTime1).getSeconds();
}
/**
* @Title aFewYearsApart
* @Description 相差几年
* @Param [oldDate, newDate]
* @Return long
* @Date 2019/7/8 15:47
* @Author QiMing
*/
public static long aFewYearsApart(LocalDateTime oldDate, LocalDateTime newDate) {
return ChronoUnit.YEARS.between(oldDate, newDate);
}
/**
* @Title aFewMonthsApart
* @Description 相差几个月
* @Param [oldDate, newDate]
* @Return long
* @Date 2019/7/8 15:49
* @Author QiMing
*/
public static long aFewMonthsApart(LocalDateTime oldDate, LocalDateTime newDate) {
return ChronoUnit.MONTHS.between(oldDate, newDate);
}
/**
* @Title aFewWEEKSApart
* @Description 相差多少周
* @Param [oldDate, newDate]
* @Return long
* @Date 2019/7/8 15:50
* @Author QiMing
*/
public static long aFewWEEKSApart(LocalDateTime oldDate, LocalDateTime newDate) {
return ChronoUnit.WEEKS.between(oldDate, newDate);
}
/**
* @Title aFewDAYSApart
* @Description 相差多少天
* @Param [oldDate, newDate]
* @Return long
* @Date 2019/7/8 15:51
* @Author QiMing
*/
public static long aFewDAYSApart(LocalDateTime oldDate, LocalDateTime newDate) {
return ChronoUnit.DAYS.between(oldDate, newDate);
}
/**
* @Title aFewHOURSApart
* @Description 相差多少小时
* @Param [oldDate, newDate]
* @Return long
* @Date 2019/7/8 15:52
* @Author QiMing
*/
public static long aFewHOURSApart(LocalDateTime oldDate, LocalDateTime newDate) {
return ChronoUnit.HOURS.between(oldDate, newDate);
}
/**
* @Title aFewHOURSApart
* @Description 相差多少分钟
* @Param [oldDate, newDate]
* @Return long
* @Date 2019/7/8 15:52
* @Author QiMing
*/
public static long aFewMINUTESApart(LocalDateTime oldDate, LocalDateTime newDate) {
return ChronoUnit.MINUTES.between(oldDate, newDate);
}
/**
* @Title aFewSECONDSApart
* @Description 相差多少秒
* @Param [oldDate, newDate]
* @Return long
* @Date 2019/7/8 15:54
* @Author QiMing
*/
public static long aFewSECONDSApart(LocalDateTime oldDate, LocalDateTime newDate) {
return ChronoUnit.SECONDS.between(oldDate, newDate);
}
/**
* @Title aFewMILLISApart
* @Description 相差多少毫秒
* @Param [oldDate, newDate]
* @Return long
* @Date 2019/7/8 15:55
* @Author QiMing
*/
public static long aFewMILLISApart(LocalDateTime oldDate, LocalDateTime newDate) {
return ChronoUnit.MILLIS.between(oldDate, newDate);
}
/**
* @Title aFewMILLISApart
* @Description 相差多少纳秒
* @Param [oldDate, newDate]
* @Return long
* @Date 2019/7/8 15:55
* @Author QiMing
*/
public static long aFewNANOSApart(LocalDateTime oldDate, LocalDateTime newDate) {
return ChronoUnit.NANOS.between(oldDate, newDate);
}
/*——————————————————— 时间相差 end ———————————————————————*/
/**
* @Title getTimestamp
* @Description 获取时间戳13位
* @Param []
* @Return long
* @Date 2019/7/8 15:59
* @Author QiMing
*/
public static long getTimestamp() {
return Clock.systemDefaultZone().millis();
}
/*——————————————————————— 时间转换 Start ——————————————————————*/
/**
* @Title dateToLocalDateTime
* @Description date转换LocalDateTime
* @Param [date]
* @Return java.time.LocalDateTime
* @Date 2019/7/8 16:05
* @Author QiMing
*/
public static LocalDateTime dateToLocalDateTime(Date date) {
// LocalDateTime.ofInstant(date.toInstant(),ZoneId.systemDefault());
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
}
/**
* @Title dateToLocalDate
* @Description date转换LocalDate
* @Param [date]
* @Return java.time.LocalDate
* @Date 2019/7/8 16:08
* @Author QiMing
*/
public static LocalDate dateToLocalDate(Date date) {
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
/**
* @Title dateToLocalTime
* @Description date转换LocalTime
* @Param [date]
* @Return java.time.LocalTime
* @Date 2019/7/8 16:08
* @Author QiMing
*/
public static LocalTime dateToLocalTime(Date date) {
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
}
/**
* @Title localDateTimeToDate
* @Description LocalDateTime转为Date
* @Param [localDateTime]
* @Return java.util.Date
* @Date 2019/7/8 16:10
* @Author QiMing
*/
public static Date localDateTimeToDate(LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
/**
* @Title localDateToDate
* @Description LocalDate -> Date,时间默认都是00
* @Param [localDate]
* @Return java.util.Date
* @Date 2019/7/8 16:13
* @Author QiMing
*/
public static Date localDateToDate(LocalDate localDate) {
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
/*——————————————————————— 时间转换 End ——————————————————————*/
/*———————————————————————— 日期与字符串、字符串与时间转换 Start ——————————————————————————*/
/**
* @Title stringConversionLocalDate
* @Description 字符串转LocalDate
* @Param [ymd]
* @Return java.time.LocalDate
* @Date 2019/7/8 16:19
* @Author QiMing
*/
public static LocalDate stringConversionLocalDate(String ymd) {
return LocalDate.parse(ymd, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT));
}
/**
* @Title stringConversionLocalDateTime
* @Description 字符串转LocalDateTime
* @Param [ymdhms]
* @Return java.time.LocalDateTime
* @Date 2019/7/8 16:22
* @Author QiMing
*/
public static LocalDateTime stringConversionLocalDateTime(String ymdhms) {
return LocalDateTime.parse(ymdhms, DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMAT));
}
/**
* @Title localDateConversionString
* @Description localDate转字符串
* @Param [localDate]
* @Return java.lang.String
* @Date 2019/7/8 16:24
* @Author QiMing
*/
public static String localDateConversionString(LocalDate localDate) {
return localDate.format(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT));
}
/**
* @Title localDateTimeConversionString
* @Description localDateTime转字符串
* @Param [localDateTime]
* @Return java.lang.String
* @Date 2019/7/8 16:25
* @Author QiMing
*/
public static String localDateTimeConversionString(LocalDateTime localDateTime) {
return localDateTime.format(DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMAT));
}
/**
* @Title localDateTimeToString
* @Description localDateTime转字符串
* @Param [localDateTime]
* @Return java.lang.String
* @Date 2019/7/8 16:28
* @Author QiMing
*/
public static String localDateTimeToString(LocalDateTime localDateTime) {
return DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMAT).format(localDateTime);
}
/*———————————————————————— 日期与字符串、字符串与时间转换 end ——————————————————————————*/
/**
* @Title timestampConversionLocalDateTime
* @Description 时间戳转换Localdatetime
* @Param [timeMillis]
* @Return java.time.LocalDateTime
* @Date 2019/7/8 16:32
* @Author QiMing
*/
public static LocalDateTime timestampConversionLocalDateTime(long timeMillis) {
Instant instant = Instant.ofEpochMilli(timeMillis);
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}
/**
* @Title localDateTimeConversiontimestamp
* @Description localDateTime 转换时间戳
* @Param [localDateTime]
* @Return long
* @Date 2019/7/8 16:34
* @Author QiMing
*/
public static long localDateTimeConversiontimestamp(LocalDateTime localDateTime) {
return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
* @Title getWeek
* @Description 获取周几
* @Param [localDate]
* @Return java.lang.String
* @Date 2019/7/8 17:08
* @Author QiMing
*/
public static String getWeek(LocalDate localDate) {
String week = String.valueOf(localDate.getDayOfWeek());
switch (week) {
case "MONDAY":
week = "周一";
break;
case "TUESDAY":
week = "周二";
break;
case "WEDNESDAY":
week = "周三";
break;
case "THURSDAY":
week = "周四";
break;
case "FRIDAY":
week = "周五";
break;
case "SATURDAY":
week = "周六";
break;
case "SUNDAY":
week = "周日";
break;
}
return week;
}
/**
* @Title localDateTimeChangeTen
* @Description LocalDateTime转换10位时间戳
* @Param [localDateTime]
* @Return long
* @Date 2019/7/9 8:39
* @Author QiMing
*/
public static long localDateTimeChangeTen(LocalDateTime localDateTime) {
long lon = localDateTimeConversiontimestamp(localDateTime) / 1000;
return Long.valueOf(String.format("%010d", lon));
}
}