程序猿不要在写日期转换工具了,万能代码片段直接拿走使用
2020/3/28 8:01:16
本文主要是介绍程序猿不要在写日期转换工具了,万能代码片段直接拿走使用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
作为开发者,每个开发项目中一定有很多的工具类,而其中百分之六七十就有一个DateUtils工具。每次都要写日期格式,yyyyMMdd。每个项目项目中使用的日期格式都不一样。终于有一天,一堆程序猿受不了了。于是把所有的日期格式都写完。放到一个工具里。使用就完了。文尾提供代码。欢迎收藏使用。
目录
- 1.JDK中DateTimeFormatter与SimpleDateFormat的区别
- 2.DatePatternEnum API
- 3.Code Example
- 4.完整代码
一、JDK中DateTimeFormatter与SimpleDateFormat的区别
旧版的API存在线程安全的问题,所谓线程安全问题,只会存在在多线程场景下。当多个线程对同一个对象的,属性进行修改时候,就很大几率会产生数据不同步问题,举一个简单的例子: A线程看到门外有一个人是小明,然后准备开门让小明进来时候,B线程把小明拉走了,让小张站门外了。结果导致A开门原本准备让小明进来,结果开门小张进来了。SimpleDateFormat的问题就是这样。format方法时候会将属性改变从而导致线程安全。因为现在建议使用新的日期API来替换老的。
二、 DatePatternEnum API
线程安全,使用简单,效率更高
DatePatternEnum API
index | pattern | desc | enum | example |
---|---|---|---|---|
0 | yyyy-MM-dd HH:mm:ss | 年月日时分秒 | DATE_TIME_PATTERN | 2019-11-04 17:06:18 |
1 | HH:mm:ss | 时分秒 | TIME_PATTERN | 17:06:18 |
2 | yyyy-MM-dd HH:mm | 年月日时分 | MINUTE_PATTERN | 2019-11-04 17:06 |
3 | yyyy-MM-dd | 年月日 | DATE_PATTERN | 2019-11-04 |
4 | yyyy-MM | 年月 | MONTH_PATTERN | 2019-11 |
5 | yyyy | 年 | YEAR_ONLY_PATTERN | 2019 |
6 | MM | 月 | MONTH_ONLY_PATTERN | 11 |
7 | dd | 日 | DAY_ONLY_PATTERN | 04 |
8 | HH | 时 | HOUR_ONLY_PATTERN | 17 |
9 | mm | 分 | MINUTE_ONLY_PATTERN | 06 |
10 | ss | 秒 | SECOND_ONLY_PATTERN | 18 |
11 | yyyy年MM月dd日 HH时mm分ss秒 | 中文格式年月日时分秒 | ZN_DATE_TIME_PATTERN | 2019年11月04日 17时06分18秒 |
12 | yyyy年MM月dd日 | 中文格式年月日 | ZN_DATE_PATTERN | 2019年11月04日 |
13 | yyyy年MM月 | 中文格式年月 | ZN_MONTH_PATTERN | 2019年11月 |
14 | yyyy年 | 中文格式年 | ZN_YEAR_ONLY_PATTERN | 2019年 |
15 | HH时mm分ss秒 | 时分秒 | ZN_TIME_PATTERN | 17时06分18秒 |
16 | yyyyMMddHHmmss | 无间隔的年月日时分秒 | GAP_LESS_DATE_TIME_PATTERN | 20191104170618 |
17 | yyyyMMdd | 无间隔的年月日 | GAP_LESS_DATE_PATTERN | 20191104 |
18 | yyyy-MM-dd HH:mm:ss.SSS | 精确到毫秒 | DATE_TIME_MS_PATTERN | 2019-11-04 17:06:18.420 |
三、Code Example
对日期的处理,首先是模板,枚举内提供了常用的日期模板,使用时候无需自己生成 SimpleDateFormat
或者是DateTimeFormatter
每个日期模板都可以直接调用 format
(Date转String) 或者 parse
(String转Date)
//①返回当前日期格式化的文本,日期表达式: DATE_TIME_PATTERN = 'yyyy-MM-dd HH:mm:ss' System.out.println(DatePatternEnum.DATE_TIME_PATTERN.format()); //②返回当前日期格式化的文本,日期表达式: DATE_TIME_PATTERN = 'yyyy年MM月dd日 HH时mm分ss秒' System.out.println(DatePatternEnum.ZN_DATE_TIME_PATTERN.format()); //③返回入参指定日期格式化的文本 System.out.println(DatePatternEnum.DATE_TIME_PATTERN.format(new Date())); //④返回日期格式化工具 SimpleDateFormat dateFormat = DatePatternEnum.TIME_PATTERN.getDateFormat(); //⑤返回新JDK日期格式化工具 DateTimeFormatter dateTimeFormatter = DatePatternEnum.TIME_PATTERN.getFormatter();
四、完整代码
import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.Map; import java.util.WeakHashMap; /** * 年-月-日 时:分:秒.毫秒->2019-11-05 17:43:29.383 * 年-月-日 时:分:秒->2019-11-05 17:43:29 * 时:分:秒->17:43:29 * 年-月-日 时:分->2019-11-05 17:43 * 年-月-日->2019-11-05 * 年-月->2019-11 * 年->2019 * 月->11 * 日->05 * 时->17 * 分->43 * 秒->29 * 中文格式年月日时分秒毫秒->2019年11月05日 17时43分29秒386毫秒 * 中文格式年月日时分秒->2019年11月05日 17时43分29秒 * 中文格式年月日->2019年11月05日 * 中文格式年月->2019年11月 * 中文格式年->2019年 * 中文格式时分秒->17时43分29秒 * 无间隔符的年月日时分秒->20191105174329 * 无间隔符的年月日时分秒毫秒->20191105174329387 * 无间隔符的年月日->20191105 * * @author liuxin */ public enum DatePatternEnum { DATE_TIME_MS_PATTERN(0, "yyyy-MM-dd HH:mm:ss.SSS", "年-月-日 时:分:秒.毫秒"), DATE_TIME_PATTERN(1, "yyyy-MM-dd HH:mm:ss", "年-月-日 时:分:秒"), TIME_PATTERN(2, "HH:mm:ss", "时:分:秒"), MINUTE_PATTERN(3, "yyyy-MM-dd HH:mm", "年-月-日 时:分"), DATE_PATTERN(4, "yyyy-MM-dd", "年-月-日"), MONTH_PATTERN(5, "yyyy-MM", "年-月"), ONLY_YEAR_PATTERN(6, "yyyy", "年"), ONLY_MONTH_PATTERN(7, "MM", "月"), ONLY_DAY_PATTERN(8, "dd", "日"), ONLY_HOUR_PATTERN(9, "HH", "时"), ONLY_MINUTE_PATTERN(10, "mm", "分"), ONLY_SECOND_PATTERN(11, "ss", "秒"), ZN_DATE_TIME_MS_PATTERN(12, "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒", "中文格式年月日时分秒毫秒"), ZN_DATE_TIME_PATTERN(13, "yyyy年MM月dd日 HH时mm分ss秒", "中文格式年月日时分秒"), ZN_DATE_PATTERN(14, "yyyy年MM月dd日", "中文格式年月日"), ZN_MONTH_PATTERN(15, "yyyy年MM月", "中文格式年月"), ZN_YEAR_ONLY_PATTERN(16, "yyyy年", "中文格式年"), ZN_TIME_PATTERN(17, "HH时mm分ss秒", "中文格式时分秒"), GAP_LESS_DATE_TIME_PATTERN(18, "yyyyMMddHHmmss", "无间隔符的年月日时分秒"), GAP_LESS_DATE_TIME_MS_PATTERN(19, "yyyyMMddHHmmssSSS", "无间隔符的年月日时分秒毫秒"), GAP_LESS_DATE_PATTERN(20, "yyyyMMdd", "无间隔符的年月日"); private int index; private String pattern; private String desc; private static final Map<DatePatternEnum, SimpleDateFormat> formatCache = new WeakHashMap<>(initialCapacity()); private static final Map<DatePatternEnum, DateTimeFormatter> formatterCache = new WeakHashMap<>(initialCapacity()); static { checkCache(); } //一个数如果是奇数的话,那么他的二进制最后一位一定为1,如果为奇数+1返回 private static int initialCapacity() { return (values().length & 1) == 1 ? values().length + 1 : values().length; } private static void checkCache() { if (formatCache.isEmpty() || formatCache.size() != values().length) { formatCache.clear(); for (DatePatternEnum datePatternEnum : values()) { formatCache.put(datePatternEnum, new SimpleDateFormat(datePatternEnum.getPattern())); } } if (formatterCache.isEmpty() || formatterCache.size() != values().length) { formatterCache.clear(); for (DatePatternEnum datePatternEnum : values()) { formatterCache.put(datePatternEnum, DateTimeFormatter.ofPattern(datePatternEnum.getPattern())); } } } DatePatternEnum(int index, String pattern, String desc) { this.index = index; this.pattern = pattern; this.desc = desc; } public int getIndex() { return index; } public String getPattern() { return pattern; } public String getDesc() { return desc; } public DateTimeFormatter getFormatter() { checkCache(); return formatterCache.getOrDefault(this, DateTimeFormatter.ofPattern(getPattern())); } private SimpleDateFormat getUnSafeDateFormat() { checkCache(); return formatCache.getOrDefault(this, new SimpleDateFormat(getPattern())); } public String format() { return LocalDateTime.now().format(getFormatter()); } public String format(Date date) { assert date != null; return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).format(getFormatter()); } public Date parse(String dateText) throws Exception { return getUnSafeDateFormat().parse(dateText); } }
这篇关于程序猿不要在写日期转换工具了,万能代码片段直接拿走使用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-05小米13T Pro系统合集:性能与摄影的极致融合,值得你升级的系统ROM
- 2024-10-01基于Python+Vue开发的医院门诊预约挂号系统
- 2024-10-01基于Python+Vue开发的旅游景区管理系统
- 2024-10-01RestfulAPI入门指南:打造简单易懂的API接口
- 2024-10-01初学者指南:了解和使用Server Action
- 2024-10-01Server Component入门指南:搭建与配置详解
- 2024-10-01React 中使用 useRequest 实现数据请求
- 2024-10-01使用 golang 将ETH账户的资产平均分散到其他账户
- 2024-10-01JWT用户校验课程:从入门到实践
- 2024-10-01Server Component课程入门指南