Java中的时间处理
- 日期时间组件使用
java.util.Date:实现类,其对象具有时间、日期组件。
java.util.Calendar:抽象类,其对象具有时间、日期组件。
java.sql.Date:实现类,其对象具有日期组件。
java.sql.Time:实现类,其对象具有时间组件。
java.sql.Timestamp:实现类,其对象具有时间日期组件。
java.text.DateFormat:抽象类,其对象格式化时间日期。
java.text.DateFormatSymbols:实现类,其对象为格式化时间日期提供参数。 long currentTime = System.currentTimeMillis(); //获取当前时间戳,从1970-01-01以来的毫秒数
LOGGER.info("{}", currentTime); java.util.Date utilDate = new java.util.Date(currentTime);
LOGGER.info("{}|{}", utilDate, utilDate.getTime()); Calendar calendar = Calendar.getInstance(); //除某些特殊地区外,默认等效于new GregorianCalendar()
calendar.setTimeInMillis(currentTime);
LOGGER.info("{}", calendar); java.sql.Date sqlDate = new java.sql.Date(currentTime);
LOGGER.info("{}|{}", sqlDate, sqlDate.getTime()); java.sql.Time sqlTime = new java.sql.Time(currentTime);
LOGGER.info("{}|{}", sqlTime, sqlTime.getTime()); java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(currentTime);
LOGGER.info("{}|{}", sqlTimestamp, sqlTimestamp.getTime());DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //默认是SimpleDateFormat
LOGGER.info("{}", dateFormat.format(utilDate));
LOGGER.info("{}", dateFormat.parse("2017-05-25 23:00:00"));输出:
1495724884755
Thu May 25 23:08:04 CST 2017|1495724884755
java.util.GregorianCalendar[time=1495724884755,...,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai"...]
2017-05-25|1495724884755
23:08:04|1495724884755
2017-05-25 23:08:04.755|1495724884755
2017-05-25 23:08:04
Thu May 25 23:00:00 CST 2017java.text.SimpleDateFormat的线程不安全问题
问题重现://final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
LOGGER.info("executing task...");
try{
return new SimpleDateFormat("yyyy-MM-dd").parse("2017-05-25");
//return format.parse("2017-05-25"); //if use shared SimpleDateFormat, executing result is not expected.
}catch (Exception ex){
LOGGER.error("Exception:", ex);
return new Date(0);
}
}
};
// pool with 5 threads
ExecutorService exec = Executors.newFixedThreadPool(5);
List<Future<Date>> results = new ArrayList<Future<Date>>();
// perform 10 date conversions
for (int i = 0; i < 10; i++) {
LOGGER.info("submit task[{}]", i);
results.add(exec.submit(task));
}
exec.shutdown();
LOGGER.info("shutdown");
// look at the results
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (Future<Date> result : results) {
LOGGER.info("{}", dateFormat.format(result.get()));
}
LOGGER.info("completed");输出(使用共享的SimpleDateFormat时,执行结果并不是预期结果):
submit task[0]
submit task[1]
submit task[2]
executing task...
submit task[3]
executing task...
submit task[4]
executing task...
executing task...
submit task[5]
executing task...
submit task[6]
submit task[7]
submit task[8]
submit task[9]
shutdown
executing task...
executing task...
executing task...
executing task...
executing task...
Exception:
java.lang.NumberFormatException: multiple points
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.text.DigitList.getDouble(DigitList.java:169)
at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at com.liq.DateTimeTest$1.call(DateTimeTest.java:65)
at com.liq.DateTimeTest$1.call(DateTimeTest.java:59)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Exception:
java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.text.DigitList.getDouble(DigitList.java:169)
at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at com.liq.DateTimeTest$1.call(DateTimeTest.java:65)
at com.liq.DateTimeTest$1.call(DateTimeTest.java:59)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Exception:
java.lang.NumberFormatException: For input string: "E.2505E2"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.text.DigitList.getDouble(DigitList.java:169)
at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at com.liq.DateTimeTest$1.call(DateTimeTest.java:65)
at com.liq.DateTimeTest$1.call(DateTimeTest.java:59)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Exception:
java.lang.NumberFormatException: For input string: "E.2505"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.text.DigitList.getDouble(DigitList.java:169)
at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at com.liq.DateTimeTest$1.call(DateTimeTest.java:65)
at com.liq.DateTimeTest$1.call(DateTimeTest.java:59)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
1970-01-01 08:00:00
1970-01-01 08:00:00
1970-01-01 08:00:00
1970-01-01 08:00:00
2017-05-25 00:00:00
2017-05-25 00:00:00
2017-05-25 00:00:00
2017-05-25 00:00:00
2017-05-25 00:00:00
2017-05-25 00:00:00
completed产生原因:
SimpleDateFormat维护一个共享的Calendar对象,如果共享SimpleDateFomat时这个Calendar也是共享的。由多个线程并发进行操作就会有问题了。protected Calendar calendar;
解决:
(1)使用局部变量
(2)使用 ThreadLocalfinal ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
//final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
LOGGER.info("executing task...");
try{
//return new SimpleDateFormat("yyyy-MM-dd").parse("2017-05-25");
//return format.parse("2017-05-25"); //if use shared SimpleDateFormat, executing result is not expected.
return df.get().parse("2017-05-25");
}catch (Exception ex){
LOGGER.error("Exception:", ex);
return new Date(0);
}
}
};(3)同步代码块 synchronized(code)
(4)使用第三方的日期处理函数:比如使用 commons-lang 包中的 FastDateFormat 工具类
参考:
Java中的时间处理的更多相关文章
- JAVA中的时间操作
java中的时间操作不外乎这四种情况: 1.获取当前时间 2.获取某个时间的某种格式 3.设置时间 4.时间的运算 好,下面就针对这四种情况,一个一个搞定. 一.获取当前时间 有两种方式可以获得,第一 ...
- Java中日期时间API小结
Java中为处理日期和时间提供了大量的API,确实有把一件简单的事情搞复杂的嫌疑,各种类:Date Time Timestamp Calendar...,但是如果能够看到时间处理的本质就可以轻松hol ...
- 1 Java中的时间类型
总结:sql中的时间转 util的时间直接赋值即可:反过来,必须先吧util下的时间转换成毫秒,再通过sql的构造器生成sql的时间格式. 1 Java中的时间类型 java.sql包下给出三个与数据 ...
- Java中的时间日期处理
程序就是输入——>处理——>输出.对数据的处理是程序员需要着重注意的地方,快速.高效的对数据进行处理时我们的追求.其中,时间日期的处理又尤为重要和平凡,此次,我将把Java中的时间日期处理 ...
- java中各种时间格式的转化
http://www.chinaitpower.com/A/2005-01-14/104881.html 使用java.util.Calendar返回间隔天数 static int g ...
- Java中六大时间类的使用和区别
关于java中六个时间类的使用和区别 java.util.Date java.sql.Date java.sql.Time java.sql.Timestamp java.text.SimpleD ...
- 【转】Java中本地时间的获取方法--不错
原文网址:http://highforest.blog.51cto.com/125539/842496/ 熟悉Oracle数据库的人,应该知道:select to_char(sysdate,'yyyy ...
- JAVA中Sql时间格式与util时间格式转换
关于时间格式转化: java.util.Date 与 java.sql.Date 互换 sql是子类 字符串转化成java.util.Date SimpleDateFormat date =n ...
- Java中的时间二三事
实习过程中对于时间的处理有很多,有的还涉及到从数据库取出时间,所以做一些总结,想到那先写到哪,慢慢补充. 首先最常见的是java.util中的Date类,这个类封装了当前的日期和时间,它实际是计 ...
随机推荐
- Tomcat之——内存溢出设置JAVA_OPTS
答案1设置Tomcat启动的初始内存其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4.可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置三.实例,以下 ...
- Sharepoint2013搜索学习笔记之设置外网内容源(四)
第一步,进入管理中心,点击管理应用程序,点击search service 应用程序进入到搜索管理配置页面,选择内容源 第二步,点击新建内容源,给内容源命名,在爬网内容类型中选网站,在爬网设置中选中仅对 ...
- Android学习笔记 Toast屏幕提示组件的使用方法
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...
- 学习使用MS SQL Server游标(CURSOR)
说实的,使用MS SQL Server这样久,游标一直没有使用过.以前实现相似的功能,都是使用WHILE循环加临时表来实现.刚才有参考网上示例练习写了一下.了解到游标概念与语法. 下面代码示例中,先是 ...
- 13本热门书籍免费送!(Python、SpingBoot、Entity Framework、Ionic、MySQL、深度学习、小程序开发等)
七月第一周,网易云社区联合清华大学出版社为大家送出13本数据分析以及移动开发的书籍(Python.SpingBoot.Entity Framework.Ionic.MySQL.深度学习.小程序开发等) ...
- C# LINQ(5)
目前都是说的单数据差距,如果多数据进行查询LINQ该如何呢? 那么LINQ就应该使用关键字 join on equals 现有代码: static void Main(string[] args) { ...
- 20165219 2017-2018-2 《Java程序设计》第4周学习总结
20165219 2017-2018-2 <Java程序设计>第4周学习总结 课本知识总结 第五章 在java中,继承时使用extends关键字,private成员也会被继承,只不过子类无 ...
- LoadRunner11_MySQL数据库脚本
记录一次压测过程中,通过LoadRunner向MySQL数据库插入大量数据的过程. [1]需要使用到MySQL的libmysql.dll动态链接库,因此需要安装MySQL:注:本地安装的MySQL最好 ...
- Linux上安装Hadoop集群(CentOS7+hadoop-2.8.3)
https://blog.csdn.net/pucao_cug/article/details/71698903 1下载hadoop 2安装3个虚拟机并实现ssh免密码登录 2.1安装3个机器 2.2 ...
- java集合之Set接口
Set集合通常不能记住元素添加的顺序,其他的操作和它的父接口基本相同.只是行为上有细微的差别,Set集合不能包含相同的元素.如果尝试添加相同的元素,调用add()方法将返回false,且新元素不能被加 ...