1. 日期时间组件使用

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

  2. 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 2017
  3. java.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)使用 ThreadLocal

            final 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 工具类

参考:

  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. 【留用】C#的一些好的书籍

    浏览博客的时候发现一篇推荐的C#书籍,感觉真的不错,涉略过几本,水平问题,没看的很深入,正在努力,留用了!!! http://www.cnblogs.com/tongming/p/3879752.ht ...

  2. 【转】Android自定义控件(二)——有弹性的ScrollView

    原文地址:http://blog.csdn.net/a105865708/article/details/17784041 实现了当手指滑动到ScrollView的顶部.底部时, 可以继续的向上.向下 ...

  3. fabric Clone

    记录下: var newObj = fabric.util.object.clone(obj); decDoc.dropCanvas.add(newObj., top: }));

  4. python中局部变量和全局变量

    局部变量,就是在函数内部定义的变量 不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响 局部变量的作用,为了临时保存数据需要在函数 在函数外边定义的变量叫做全局变量 全局变量能够在所有 ...

  5. pycharm自动调整html页面代码缩进不正确的解决办法

    pycharm自动调整html页面代码缩进不正确的解决办法

  6. [AGC005C]Tree Restoring 构造

    Description ​ 给出一个数组a,要求构造一颗树,使节点x距离最远的点的距离为\(a_x\). Input ​ 第一行一个正整数NN(2≤N≤1002≤N≤100) ​ 接下来一行,有NN个 ...

  7. 【SSO单点系列】(5):CAS4.0 单点流程序列图

    刚过元旦假期,感觉自己好久没写博客了,今天更新一篇,主要是CAS 的一个流程图. ps: 这两张图 是直接从官网上找的,都是简单的英语,我这种英语四级没过都看得懂,大家应该没有压力. 1.CAS 基本 ...

  8. SQLServer如何清除缓存?

    --1. 将当前数据库的全部脏页写入磁盘.“脏页”是已输入缓存区高速缓存且已修改但尚未写入磁盘的数据页. -- CHECKPOINT 可创建一个检查点,在该点保证全部脏页都已写入磁盘,从而在以后的恢复 ...

  9. (Keil) Debug & Simulation 操作

    0x00 printf在MCU環境下print debug error message,利用Logic Analyzer模擬MCU register or GPIO狀態. 若是要要使用printf函數 ...

  10. mysql数据库分库分表shardingjdbc

    分库分表理解 分库分表应用于互联网的两个场景;大量数据和高并发,通常策略有两种:垂直分库,水平拆分 垂直拆分:是根据业务将一个库拆分为多个库,将一个表拆分为多个表,例如:将不常用的字段和经常访问的字段 ...