1. 日期时间组件使用

    java.util.Date:实现类,其对象具有时间、日期组件。
    java.util.Calendar:抽象类,其对象具有时间、日期组件。
    java.sql.Date:实现类,其对象具有日期组件。
    java.sql.Time:实现类,其对象具有时间组件。
    java.sql.Timestamp:实现类,其对象具有时间日期组件。
    java.text.DateFormat:抽象类,其对象格式化时间日期。
    java.text.DateFormatSymbols:实现类,其对象为格式化时间日期提供参数。

    1. long currentTime = System.currentTimeMillis(); //获取当前时间戳,从1970-01-01以来的毫秒数
    2. LOGGER.info("{}", currentTime);
    3.  
    4. java.util.Date utilDate = new java.util.Date(currentTime);
    5. LOGGER.info("{}|{}", utilDate, utilDate.getTime());
    6.  
    7. Calendar calendar = Calendar.getInstance(); //除某些特殊地区外,默认等效于new GregorianCalendar()
    8. calendar.setTimeInMillis(currentTime);
    9. LOGGER.info("{}", calendar);
    10.  
    11. java.sql.Date sqlDate = new java.sql.Date(currentTime);
    12. LOGGER.info("{}|{}", sqlDate, sqlDate.getTime());
    13.  
    14. java.sql.Time sqlTime = new java.sql.Time(currentTime);
    15. LOGGER.info("{}|{}", sqlTime, sqlTime.getTime());
    16.  
    17. java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(currentTime);
    18. LOGGER.info("{}|{}", sqlTimestamp, sqlTimestamp.getTime());
    1. 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"));

    输出:

    1. 1495724884755
    2. Thu May 25 23:08:04 CST 2017|1495724884755
    3. java.util.GregorianCalendar[time=1495724884755,...,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai"...]
    4. 2017-05-25|1495724884755
    5. 23:08:04|1495724884755
    6. 2017-05-25 23:08:04.755|1495724884755
    7. 2017-05-25 23:08:04
    8. Thu May 25 23:00:00 CST 2017
  2. java.text.SimpleDateFormat的线程不安全问题
    问题重现:

    1. //final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    2.  
    3. Callable<Date> task = new Callable<Date>() {
    4. @Override
    5. public Date call() throws Exception {
    6. LOGGER.info("executing task...");
    7. try{
    8. return new SimpleDateFormat("yyyy-MM-dd").parse("2017-05-25");
    9. //return format.parse("2017-05-25"); //if use shared SimpleDateFormat, executing result is not expected.
    10. }catch (Exception ex){
    11. LOGGER.error("Exception:", ex);
    12. return new Date(0);
    13. }
    14. }
    15. };
    16. // pool with 5 threads
    17. ExecutorService exec = Executors.newFixedThreadPool(5);
    18. List<Future<Date>> results = new ArrayList<Future<Date>>();
    19. // perform 10 date conversions
    20. for (int i = 0; i < 10; i++) {
    21. LOGGER.info("submit task[{}]", i);
    22. results.add(exec.submit(task));
    23. }
    24. exec.shutdown();
    25. LOGGER.info("shutdown");
    26. // look at the results
    27. DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    28. for (Future<Date> result : results) {
    29. LOGGER.info("{}", dateFormat.format(result.get()));
    30. }
    31. LOGGER.info("completed");

    输出(使用共享的SimpleDateFormat时,执行结果并不是预期结果):

    1. submit task[0]
    2. submit task[1]
    3. submit task[2]
    4. executing task...
    5. submit task[3]
    6. executing task...
    7. submit task[4]
    8. executing task...
    9. executing task...
    10. submit task[5]
    11. executing task...
    12. submit task[6]
    13. submit task[7]
    14. submit task[8]
    15. submit task[9]
    16. shutdown
    17. executing task...
    18. executing task...
    19. executing task...
    20. executing task...
    21. executing task...
    22. Exception
    23. java.lang.NumberFormatException: multiple points
    24. at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1890)
    25. at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    26. at java.lang.Double.parseDouble(Double.java:538)
    27. at java.text.DigitList.getDouble(DigitList.java:169)
    28. at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
    29. at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
    30. at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
    31. at java.text.DateFormat.parse(DateFormat.java:364)
    32. at com.liq.DateTimeTest$1.call(DateTimeTest.java:65)
    33. at com.liq.DateTimeTest$1.call(DateTimeTest.java:59)
    34. at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    35. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    36. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    37. at java.lang.Thread.run(Thread.java:745)
    38. Exception
    39. java.lang.NumberFormatException: empty String
    40. at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
    41. at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    42. at java.lang.Double.parseDouble(Double.java:538)
    43. at java.text.DigitList.getDouble(DigitList.java:169)
    44. at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
    45. at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
    46. at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
    47. at java.text.DateFormat.parse(DateFormat.java:364)
    48. at com.liq.DateTimeTest$1.call(DateTimeTest.java:65)
    49. at com.liq.DateTimeTest$1.call(DateTimeTest.java:59)
    50. at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    51. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    52. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    53. at java.lang.Thread.run(Thread.java:745)
    54. Exception
    55. java.lang.NumberFormatException: For input string: "E.2505E2"
    56. at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
    57. at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    58. at java.lang.Double.parseDouble(Double.java:538)
    59. at java.text.DigitList.getDouble(DigitList.java:169)
    60. at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
    61. at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
    62. at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
    63. at java.text.DateFormat.parse(DateFormat.java:364)
    64. at com.liq.DateTimeTest$1.call(DateTimeTest.java:65)
    65. at com.liq.DateTimeTest$1.call(DateTimeTest.java:59)
    66. at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    67. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    68. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    69. at java.lang.Thread.run(Thread.java:745)
    70. Exception
    71. java.lang.NumberFormatException: For input string: "E.2505"
    72. at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
    73. at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    74. at java.lang.Double.parseDouble(Double.java:538)
    75. at java.text.DigitList.getDouble(DigitList.java:169)
    76. at java.text.DecimalFormat.parse(DecimalFormat.java:2056)
    77. at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
    78. at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
    79. at java.text.DateFormat.parse(DateFormat.java:364)
    80. at com.liq.DateTimeTest$1.call(DateTimeTest.java:65)
    81. at com.liq.DateTimeTest$1.call(DateTimeTest.java:59)
    82. at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    83. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    84. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    85. at java.lang.Thread.run(Thread.java:745)
    86. 1970-01-01 08:00:00
    87. 1970-01-01 08:00:00
    88. 1970-01-01 08:00:00
    89. 1970-01-01 08:00:00
    90. 2017-05-25 00:00:00
    91. 2017-05-25 00:00:00
    92. 2017-05-25 00:00:00
    93. 2017-05-25 00:00:00
    94. 2017-05-25 00:00:00
    95. 2017-05-25 00:00:00
    96. completed

    产生原因:
    SimpleDateFormat维护一个共享的Calendar对象,如果共享SimpleDateFomat时这个Calendar也是共享的。由多个线程并发进行操作就会有问题了。

    1. protected Calendar calendar;

    解决:
    (1)使用局部变量
    (2)使用 ThreadLocal

    1. final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
    2. @Override
    3. protected DateFormat initialValue() {
    4. return new SimpleDateFormat("yyyy-MM-dd");
    5. }
    6. };
    7. //final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    8.  
    9. Callable<Date> task = new Callable<Date>() {
    10. @Override
    11. public Date call() throws Exception {
    12. LOGGER.info("executing task...");
    13. try{
    14. //return new SimpleDateFormat("yyyy-MM-dd").parse("2017-05-25");
    15. //return format.parse("2017-05-25"); //if use shared SimpleDateFormat, executing result is not expected.
    16. return df.get().parse("2017-05-25");
    17. }catch (Exception ex){
    18. LOGGER.error("Exception:", ex);
    19. return new Date(0);
    20. }
    21. }
    22. };

    (3)同步代码块 synchronized(code)
    (4)使用第三方的日期处理函数:比如使用 commons-lang 包中的 FastDateFormat 工具类

参考:

  1. 如何在Java 8中愉快地处理日期和时间
  2. Java中的时间日期处理
  3. 详解SimpleDateFormat的线程安全问题与解决方案
  4. java中关于时间的处理 *
  5. 日历字段之间的转换

Java中的时间处理的更多相关文章

  1. JAVA中的时间操作

    java中的时间操作不外乎这四种情况: 1.获取当前时间 2.获取某个时间的某种格式 3.设置时间 4.时间的运算 好,下面就针对这四种情况,一个一个搞定. 一.获取当前时间 有两种方式可以获得,第一 ...

  2. Java中日期时间API小结

    Java中为处理日期和时间提供了大量的API,确实有把一件简单的事情搞复杂的嫌疑,各种类:Date Time Timestamp Calendar...,但是如果能够看到时间处理的本质就可以轻松hol ...

  3. 1 Java中的时间类型

    总结:sql中的时间转 util的时间直接赋值即可:反过来,必须先吧util下的时间转换成毫秒,再通过sql的构造器生成sql的时间格式. 1 Java中的时间类型 java.sql包下给出三个与数据 ...

  4. Java中的时间日期处理

    程序就是输入——>处理——>输出.对数据的处理是程序员需要着重注意的地方,快速.高效的对数据进行处理时我们的追求.其中,时间日期的处理又尤为重要和平凡,此次,我将把Java中的时间日期处理 ...

  5. java中各种时间格式的转化

    http://www.chinaitpower.com/A/2005-01-14/104881.html 使用java.util.Calendar返回间隔天数         static int g ...

  6. Java中六大时间类的使用和区别

    关于java中六个时间类的使用和区别 java.util.Date java.sql.Date  java.sql.Time  java.sql.Timestamp java.text.SimpleD ...

  7. 【转】Java中本地时间的获取方法--不错

    原文网址:http://highforest.blog.51cto.com/125539/842496/ 熟悉Oracle数据库的人,应该知道:select to_char(sysdate,'yyyy ...

  8. JAVA中Sql时间格式与util时间格式转换

    关于时间格式转化: java.util.Date 与 java.sql.Date 互换 sql是子类 字符串转化成java.util.Date     SimpleDateFormat date =n ...

  9. Java中的时间二三事

    实习过程中对于时间的处理有很多,有的还涉及到从数据库取出时间,所以做一些总结,想到那先写到哪,慢慢补充.    首先最常见的是java.util中的Date类,这个类封装了当前的日期和时间,它实际是计 ...

随机推荐

  1. 关于在jeecms中css,图片,html,模板是如何组装成——part1

    先从HTML入手:index.html <!DOCTYPE HTML> <html> <meta name="viewport" content=&q ...

  2. C#字符串string的常用使用方法(转载)

    1--->字符串的声明: 1.string s=new string(char[] arr)     //根据一个字符数组声明字符串,即将字符字组转化为字符串. 2.string s=new s ...

  3. 转:[web]javascript 增加表單的input

    利用javascript增加form的input 這是js的部份 //用來區分不同input的name var element_count = 0; function add_element(obj) ...

  4. Qt绘制简单的风向玫瑰图代码

    1.绘制简单的风向玫瑰图代码2.主要使用QPainter3.在子widget上绘制需要使用widget监视事件 eventfilter update();//更新界面 //镜头12 QPainter ...

  5. CentOS 系统管理与yum软件仓库搭建

    重启 reboot shutdown -r now init 6 关闭 init 0 shutdown -h now shutdown -h 20:25 #8点25关机查看内存 free CPU利用率 ...

  6. asp.net core 外部认证多站点模式实现

    PS:之前因为需要扩展了微信和QQ的认证,使得网站是可以使用QQ和微信直接登录.github 传送门 .然后有小伙伴问,能否让这个配置信息(appid, appsecret)按需改变,而不是在 Con ...

  7. WinForm中ListBox的使用

    获取选中数据:listbox.SelectedItem as XXX 重绘每一行item DrawMode设置为DrawMode.OwnerDrawVariable 然后实现DrawItem(obje ...

  8. 复杂业务下向Mysql导入30万条数据代码优化的踩坑记录

    从毕业到现在第一次接触到超过30万条数据导入MySQL的场景(有点low),就是在顺丰公司接入我司EMM产品时需要将AD中的员工数据导入MySQL中,因此楼主负责的模块connector就派上了用场. ...

  9. vs2015+opencv3.3.1 +Eigen 3.3.4 c++实现 薄膜插值 泊松图像编辑(v=0||Δf=0)

    #include "core/core.hpp" #include "highgui/highgui.hpp" #include "imgproc/i ...

  10. 【转】C#、面向对象、设计模式学习

    源地址:http://www.cnblogs.com/cj723/archive/2007/04/02/697431.html