关于Parse字符串为时间一次被坑经历
2016-09-09 09:55
399 查看
在Java代码中发现一个bug,就是本来更新为时间的内容更新为一些奇怪的内容,比如20819这种形式,本来更新的时间都是近期不会超过一年,
为什么会出现这种情况,非常奇怪,遂调试下代码,跟踪发现要匹配的字符串内容和预想的日期格式不符合,代码处理这种情况是抛出异常,
然后用今天的日期替代,结果没成功,代码大概如下:
按照本来的思路,应该是解析发生异常,然后时间为当前时间,结果打印为:2091-1-1 0:00:00
可见,就算格式和实际的不符合,也不会抛出异常,仔细检查后发现,0901也当做月份来处理,即901,然后除12的话,等于75,再加上年份2016,
刚好是2091年,这个确实和我们的预期不符,所以在做这类转化前最好确认下位数防止这种奇怪的现象。
后来了解到SimpleDateFormat的生成开销比较大,尽量少用,而且不是线程安全的函数,如果网上提供了一个高效的用法:
或者
说明:使用ThreadLocal, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。
为什么会出现这种情况,非常奇怪,遂调试下代码,跟踪发现要匹配的字符串内容和预想的日期格式不符合,代码处理这种情况是抛出异常,
然后用今天的日期替代,结果没成功,代码大概如下:
String dt = "20160901"; SimpleDateFormat dateFm = new SimpleDateFormat("yyyyMM"); Date strSuffix = null; try{ strSuffix = dateFm.parse(dt); } catch(Exception e){ strSuffix = new Date(); e.printStackTrace(); } System.out.println("result date:"+strSuffix.toLocaleString());
按照本来的思路,应该是解析发生异常,然后时间为当前时间,结果打印为:2091-1-1 0:00:00
可见,就算格式和实际的不符合,也不会抛出异常,仔细检查后发现,0901也当做月份来处理,即901,然后除12的话,等于75,再加上年份2016,
刚好是2091年,这个确实和我们的预期不符,所以在做这类转化前最好确认下位数防止这种奇怪的现象。
后来了解到SimpleDateFormat的生成开销比较大,尽量少用,而且不是线程安全的函数,如果网上提供了一个高效的用法:
package com.peidasoft.dateformat; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class ThreadLocalDateUtil { private static final String date_format = "yyyy-MM-dd HH:mm:ss"; private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(); public static DateFormat getDateFormat() { DateFormat df = threadLocal.get(); if(df==null){ df = new SimpleDateFormat(date_format); threadLocal.set(df); } return df; } public static String formatDate(Date date) throws ParseException { return getDateFormat().format(date); } public static Date parse(String strDate) throws ParseException { return getDateFormat().parse(strDate); } }
或者
package com.peidasoft.dateformat; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class ConcurrentDateUtil { private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } }; public static Date parse(String dateStr) throws ParseException { return threadLocal.get().parse(dateStr); } public static String format(Date date) { return threadLocal.get().format(date); } }
说明:使用ThreadLocal, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。
相关文章推荐
- 关于Parse字符串为时间一次被坑经历
- 一次关于旨在降低编译时间的整改工作(c++)
- 关于时间转字符串的格式设置的几种策略
- 使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历
- [C语言常见面试题]查询一个字符串中第一个只出现一次的字符,要求时间复杂度为O(1)
- 关于一次忘记mysql root账号密码的经历
- 关于Python中时间与字符串直接的转换...
- 关于java将String类型的时间字符串转换为Date类型的问题
- 关于串口问题的一次出差经历
- 剑指offer-第五章优化时间和空间效率(在字符串中第一次出现切只出现一次的字符)
- 关于图片显示类与GDI经历的一次弱智错误
- 关于nginx和cacti的一次排错经历
- 关于date中时间字符串的格式
- 使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历
- 一次关于旨在降低编译时间的整改工作(vc++)
- 关于c#对日期时间字符串的格式化操作
- 一次关于top的调优经历
- 求出字符串中第一个只出现一次的字符,要求时间复杂度小于O(2n)
- 使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历
- 关于“时间”的一次探索 关于js时区iso,utc等完美解答