项目结束,大量使用到日期记录 分享一下日期工具类
程序员文章站
2022-07-15 14:56:41
...
public class DateUtil {
/**
* 锁对象
*/
private static final Object lockObj = new Object();
/**
* 存放不同的日期模板格式的sdf的Map
*/
private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<>();
/**
* 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
*/
private static SimpleDateFormat getSdf(final String pattern) {
ThreadLocal<SimpleDateFormat> tl = sdfMap.get(pattern);
// 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
if (tl == null) {
synchronized (lockObj) {
tl = sdfMap.get(pattern);
if (tl == null) {
// 只有Map中还没有这个pattern的sdf才会生成新的sdf并放入map
System.out.println("put new sdf of pattern " + pattern + " to map");
// 这里是关键,使用ThreadLocal<SimpleDateFormat>替代原来直接new SimpleDateFormat
tl = ThreadLocal.withInitial(() -> {
System.out.println("thread: " + Thread.currentThread() + " init pattern: " + pattern);
return new SimpleDateFormat(pattern);
});
sdfMap.put(pattern, tl);
}
}
}
return tl.get();
}
/**
* 使用ThreadLocal<SimpleDateFormat>来获取SimpleDateFormat,这样每个线程只会有一个SimpleDateFormat
* 如果新的线程中没有SimpleDateFormat,才会new一个
*/
public String format(Date date, String pattern) {
return getSdf(pattern).format(date);
}
public Date parse(String dateStr, String pattern) throws ParseException {
return getSdf(pattern).parse(dateStr);
}
/**
* 计算参数时间戳 与 当前时间的天数差
* 只取时间戳中的月日 与当前年份进行拼接 得到 今年的该月该日
* 今年的该月该日 与 当前时间计算 得出 天数差
* 如果今年的该月该日 已过 那么就计算明年的该月该日 与当前时间的 天数差
* @param dateSql
* @return
*/
public static Integer getCountdownDays(Date dateSql,Integer type){
//获取数据库中对应的时间戳对应的月日 并 附加到今年上面
String stringTimeNow = getStringTime(new Date()).substring(0, 4);
String stringTimeSql = getStringTime(dateSql).substring(4);
stringTimeSql=stringTimeNow+stringTimeSql;
//得到拼接好的数据库时间戳 这里存在一个问题 如 2-29号 如果当前没有2.29号 那么会自动向后一天
Long timeSqlDate = getTimestamp(stringTimeSql);
Long timeNowDate = getTimestamp(getStringTime(new Date()));
int timeDistance;
if (type==1){
timeDistance= getTimeDistance(new Date(timeSqlDate),new Date(timeNowDate));
}else {
timeDistance= getTimeDistance(new Date(timeNowDate), new Date(timeSqlDate));
}
if (timeDistance == 0 ){
//当前就位 纪恋日
return 0;
}else if (timeDistance>0){
//纪恋日还没有到
return timeDistance;
}else {
//纪恋日已过 自动加一年计算
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(timeSqlDate));
calendar.add(Calendar.YEAR, 1);//增加一年
timeSqlDate= calendar.getTime().getTime();
return getTimeDistance(new Date(timeNowDate), new Date(timeSqlDate));
}
}
public static int getTimeDistance(Date beginDate , Date endDate ) {
Calendar beginCalendar = Calendar.getInstance();
beginCalendar.setTime(beginDate);
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
long beginTime = beginCalendar.getTime().getTime();
long endTime = endCalendar.getTime().getTime();
int betweenDays = (int)((endTime - beginTime) / (1000 * 60 * 60 *24));//先算出两时间的毫秒数之差大于一天的天数
endCalendar.add(Calendar.DAY_OF_MONTH, -betweenDays);//使endCalendar减去这些天数,将问题转换为两时间的毫秒数之差不足一天的情况
endCalendar.add(Calendar.DAY_OF_MONTH, -1);//再使endCalendar减去1天
if(beginCalendar.get(Calendar.DAY_OF_MONTH)==endCalendar.get(Calendar.DAY_OF_MONTH))//比较两日期的DAY_OF_MONTH是否相等
return betweenDays + 1; //相等说明确实跨天了
else
return betweenDays; //不相等说明确实未跨天
}
/**
* @desc 字符串转时间戳
* @param
* @example time="2019-04-19 00:00:00"
**/
public static Long getTimestamp(String time) {
Long timestamp = null;
try {
timestamp = new SimpleDateFormat("yyyy-MM-dd").parse(time).getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return timestamp;
}
/**
* @desc 时间戳转字符串
* @param
* @example timestamp=1558322327000
**/
public static String getStringTime(Date timestamp) {
return new SimpleDateFormat("yyyy-MM-dd").format(timestamp.getTime());
}
/**
* @desc 时间戳转字符串
* @param
* @example timestamp=1558322327000
**/
public static String getStringTimeMore(Date timestamp) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timestamp.getTime());
}
//获取过去或未来任意天内的日期数组(特别定制,去除当前一天)
public List<String> getDateList(int days){
List<String> list = new ArrayList<>();
int days_temp = Math.abs(days); //对不确定正负的days取绝对值
Calendar calendar = Calendar.getInstance();
if(days > 0){ //表示需要的是未来几天的数据
calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + days_temp);
for(int i = 1; i < days_temp; i++){
calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - 1);
String str_date = this.format(calendar.getTime(),"yyyy-MM-dd");
list.add(str_date);
}
}else { //表示需要的是过去几天的数据
calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - days_temp);
for(int i = 1; i < days_temp; i++){
calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 1);
String str_date = this.format(calendar.getTime(),"yyyy-MM-dd");
list.add(str_date);
}
}
return list;
}
/**
* 获取今天开始时间
*/
public static Long getStartTime() {
Calendar todayStart = Calendar.getInstance();
todayStart.set(Calendar.HOUR_OF_DAY, 0);
todayStart.set(Calendar.MINUTE, 0);
todayStart.set(Calendar.SECOND, 0);
todayStart.set(Calendar.MILLISECOND, 0);
return todayStart.getTime().getTime();
}
/**
* 获取今天结束时间
*/
public static Long getEndTime() {
Calendar todayEnd = Calendar.getInstance();
todayEnd.set(Calendar.HOUR_OF_DAY, 23);
todayEnd.set(Calendar.MINUTE, 59);
todayEnd.set(Calendar.SECOND, 59);
todayEnd.set(Calendar.MILLISECOND, 999);
return todayEnd.getTime().getTime();
}
public static String dealDateFormat(String oldDate) {
Date date1 = null;
DateFormat df2 = null;
try {
oldDate= oldDate.replace("Z", " UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
Date date = df.parse(oldDate);
SimpleDateFormat df1 = new SimpleDateFormat ("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
date1 = df1.parse(date.toString());
df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} catch (ParseException e) {
e.printStackTrace();
}
return df2.format(date1);
}
/**
* start
* 本周开始时间戳 - 以星期一为本周的第一天
*/
public static long getWeekStartTime() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat( "yyyyMMdd", Locale. getDefault());
Calendar cal = Calendar.getInstance();
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0,
0, 0);
int day_of_week = cal.get(Calendar. DAY_OF_WEEK) - 1;
if (day_of_week == 0 ) {
day_of_week = 7 ;
}
cal.add(Calendar.DATE , -day_of_week + 1 );
return cal.getTime().getTime();
}
/**
* end
* 本周结束时间戳 - 以星期一为本周的第一天
*/
public static long getWeekEndTime() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat( "yyyyMMdd", Locale. getDefault());
Calendar cal = Calendar.getInstance();
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 23,
59, 59);
int day_of_week = cal.get(Calendar. DAY_OF_WEEK) - 1;
if (day_of_week == 0 ) {
day_of_week = 7 ;
}
cal.add(Calendar.DATE , -day_of_week + 7 );
return cal.getTime().getTime() ;
}
/**
* 获取当月开始时间戳
*
* @param timeStamp 毫秒级时间戳
* @param
* @return
*/
public static Long getMonthStartTime(Long timeStamp) {
Calendar calendar = Calendar.getInstance();// 获取当前日期
calendar.setTimeInMillis(timeStamp);
calendar.add(Calendar.YEAR, 0);
calendar.add(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTimeInMillis();
}
/**
* 获取当月的结束时间戳
*
* @param timeStamp 毫秒级时间戳
* @param
* @return
*/
public static Long getMonthEndTime(Long timeStamp) {
Calendar calendar = Calendar.getInstance();// 获取当前日期
calendar.setTimeInMillis(timeStamp);
calendar.add(Calendar.YEAR, 0);
calendar.add(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));// 获取当前月最后一天
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 999);
return calendar.getTimeInMillis();
}
}
上一篇: 工具类-时间处理类
下一篇: 工具类-Map处理类