• SimpleDateFormat、FastDateFormat和Joda-Time的介绍


    众所周知,SimpleDateFormat是线程不安全的,不能多个线程公用。而FastDateFormat和Joda-Time都是线程安全的,可以放心使用。

    SimpleDateFormat是JDK提供的,不需要依赖第三方jar包,而其他两种都得依赖第三方jar包。

    SimpleDateFormat和FastDateFormat主要都是对时间的格式化

    SimpleDateFormat在对时间进行格式化的方法format中,会先对calendar对象进行setTime的赋值,若是有多个线程同时操作一个SimpleDateFormat实例的话,就会对calendar的赋值进行覆盖,进而产生问题。

    有三种方法可以解决这个问题:

    1、在每次需要使用的时候,进行SimpleDateFormat实例的创建,这种方式会导致创建一些对象实例,占用一些内存,不建议这样使用。

    2、使用同步的方式,在调用方法的时候加上synchronized,这样可以让线程调用方法时,进行加锁,也就是会造成线程间的互斥,对性能影响比较大。

    3、使用ThreadLocal进行保存,相当于一个线程只会有一个实例,进而减少了实例数量,也防止了线程间的互斥,推荐使用这种方式。

    FastDateFormat是线程安全的,可以直接使用,不必考虑多线程的情况

    FastDateFormat format = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");  
    System.out.println(format.format(new Date()));  
      
    // 可以使用DateFormatUtils类来操作,方法里面也是使用的FastDateFormat类来做的  
    System.out.println(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));  
    

    Joda-Time与以上两种有所区别,不仅仅可以对时间进行格式化输出,而且可以生成瞬时时间值,并与Calendar、Date等对象相互转化,极大的方便了程序的兼容性。

    Joda-Time的类具有不可变性,因此他们的实例是无法修改的,就跟String的对象一样。

    这种不可变性提现在所有API方法中,这些方法返回的都是新的类实例,与原来实例不同。

    Joda-Time示例:

    // 得到当前时间  
    Date currentDate = new Date();  
    DateTime dateTime = new DateTime();  // DateTime.now()  
      
    System.out.println(currentDate.getTime());  
    System.out.println(dateTime.getMillis());  
      
    // 指定某一个时间,如2016-08-29 15:57:02  
    Date oneDate = new Date(1472457422728L);  
    DateTime oneDateTime = new DateTime(1472457422728L);  
    DateTime oneDateTime1 = new DateTime(2016, 8, 29, 15, 57, 2, 728);  
      
    System.out.println(oneDate.toString());  
    System.out.println(oneDateTime.toString());  // datetime默认的输出格式为yyyy-MM-ddTHH:mm:ss.SSS  
    System.out.println(oneDateTime1.toString("MM/dd/yyyy hh:mm:ss.SSSa"));  // 直接就可以输出规定的格式  
      
    // DateTime和Date之间的转换  
    Date convertDate = new Date();  
    DateTime dt1 = new DateTime(convertDate);  
    System.out.println(dt1.toString());  
      
    Date d1 = dt1.toDate();  
    System.out.println(d1.toString());  
      
    // DateTime和Calendar之间的转换  
    Calendar c1 = Calendar.getInstance();  
    DateTime dt2 = new DateTime(c1);  
    System.out.println(dt2.toString());  
      
    Calendar c2 = dt2.toCalendar(null);  // 默认时区Asia/Shanghai  
    System.out.println(c2.getTimeZone());  
      
    // 时间格式化  
    DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");  
    DateTime dt3 = DateTime.parse("2016-08-29 13:32:33", formatter);  
    System.out.println(dt3.toString());  
    // 若是不指定格式,会采用默认的格式,yyyy-MM-ddTHH:mm:ss.SSS,若被解析字符串只到年月日,后面的时分秒会全部默认为0  
    DateTime dt4 = DateTime.parse("2016-08-29T");  
    System.out.println(dt4.toString());  
    // 输出locale 输出2016年08月29日 16:43:14 星期一  
    System.out.println(new DateTime().toString("yyyy年MM月dd日 HH:mm:ss EE", Locale.CHINESE));  
      
    // 计算两个日期间隔的天数  
    LocalDate start = new DateTime().toLocalDate();  
    LocalDate end = new LocalDate(2016, 8, 25);  
    System.out.println(Days.daysBetween(start ,end).getDays()); // 这里要求start必须早于end,否则计算出来的是个负数  
    // 相同的还有间隔年数、月数、小时数、分钟数、秒数等计算  
    // 类如Years、Hours等  
      
    // 对日期的加减操作  
    DateTime dt5 = new DateTime();  
    dt5 = dt5.plusYears(1)          // 增加年  
            .plusMonths(1)          // 增加月  
            .plusDays(1)            // 增加日  
            .minusHours(1)          // 减小时  
            .minusMinutes(1)        // 减分钟  
            .minusSeconds(1);       // 减秒数  
    System.out.println(dt5.toString());  
      
    // 判断是否闰月  
    DateTime dt6 = new DateTime();  
    DateTime.Property month = dt6.monthOfYear();  
    System.out.println(month.isLeap());  
    

    转载自:https://jjhpeopl.iteye.com/blog/2321528

  • 相关阅读:
    Java 面试 --- 3
    Java 面试-- 1
    面试之痛 -- 二叉树 前序 中序 后序
    java 事务
    深入理解mybatis
    hibernate
    mybatis 原理
    spring 原理
    spring aop
    spring 事务
  • 原文地址:https://www.cnblogs.com/DiZhang/p/12544774.html
Copyright © 2020-2023  润新知