暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java新特性解读JDK8之日期时间处理类

227decision 2019-12-30
1824

JDK8之前处理日期时间类

SimpleDateFormat,java.util.Date,Calendar

缺点:

  1. 线程不安全;

  2. API操作麻烦;


    //java.util.Date构造日期时间源码,cdate为实例变量,导致线程不安全
    @Deprecated
    public Date(int year, int month, int date, int hrs, int min, int sec) {
    int y = year + 1900;
    // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
    if (month >= 12) {
    y += month 12;
    month %= 12;
    } else if (month < 0) {
    y += CalendarUtils.floorDivide(month, 12);
    month = CalendarUtils.mod(month, 12);
    }
    BaseCalendar cal = getCalendarSystem(y);
    cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
    cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
    getTimeImpl();
    cdate = null;
    }


      //Calendar构造函数源码,其中也是使用了实例变量,导致线程不安全
      protected Calendar(TimeZone zone, Locale aLocale)
      {
      fields = new int[FIELD_COUNT];
      isSet = new boolean[FIELD_COUNT];
      stamp = new int[FIELD_COUNT];


      this.zone = zone;
      setWeekCountData(aLocale);
      }


        //SimpleDateFormat中format方法,calendar为实例变量,导致线程不安全
        @Override
        public StringBuffer format(Date date, StringBuffer toAppendTo,
        FieldPosition pos)
        {
        pos.beginIndex = pos.endIndex = 0;
        return format(date, toAppendTo, pos.getFieldDelegate());
        }


        // Called from Format after creating a FieldDelegate
        private StringBuffer format(Date date, StringBuffer toAppendTo,
        FieldDelegate delegate) {
        // Convert input date to time field list
        calendar.setTime(date);


        boolean useDateFormatSymbols = useDateFormatSymbols();


        for (int i = 0; i < compiledPattern.length; ) {
        int tag = compiledPattern[i] >>> 8;
        int count = compiledPattern[i++] & 0xff;
        if (count == 255) {
        count = compiledPattern[i++] << 16;
        count |= compiledPattern[i++];
        }


        switch (tag) {
        case TAG_QUOTE_ASCII_CHAR:
        toAppendTo.append((char)count);
        break;


        case TAG_QUOTE_CHARS:
        toAppendTo.append(compiledPattern, i, count);
        i += count;
        break;


        default:
        subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
        break;
        }
        }
        return toAppendTo;
        }


        JDK8处理日期时间类

        核心类: LocalDate,LocalTime,Localdatetime,DateTimeFormatter

          //LocalDate线程安全类,获取LocalDate对象create方法使用 new 
          //LocalTime和Localdatetime也都是线程安全类,获取对象也都使用new,这里不再列出源码
          private static LocalDate create(int year, int month, int dayOfMonth) {
          if (dayOfMonth > 28) {
          int dom = 31;
          switch (month) {
          case 2:
          dom = (IsoChronology.INSTANCE.isLeapYear(year) ? 29 : 28);
          break;
          case 4:
          case 6:
          case 9:
          case 11:
          dom = 30;
          break;
          }
          if (dayOfMonth > dom) {
          if (dayOfMonth == 29) {
          throw new DateTimeException("Invalid date 'February 29' as '" + year + "' is not a leap year");
          } else {
          throw new DateTimeException("Invalid date '" + Month.of(month).name() + " " + dayOfMonth + "'");
          }
          }
          }
          return new LocalDate(year, month, dayOfMonth);


             //DateTimeFormatter线程安全,StringBuilder和new DateTimePrintContext保证线程安全
            public String format(TemporalAccessor temporal) {
            StringBuilder buf = new StringBuilder(32);
            formatTo(temporal, buf);
            return buf.toString();
            }


            public void formatTo(TemporalAccessor temporal, Appendable appendable) {
            Objects.requireNonNull(temporal, "temporal");
            Objects.requireNonNull(appendable, "appendable");
            try {
            DateTimePrintContext context = new DateTimePrintContext(temporal, this);
            if (appendable instanceof StringBuilder) {
            printerParser.format(context, (StringBuilder) appendable);
            } else {
            // buffer output to avoid writing to appendable in case of error
            StringBuilder buf = new StringBuilder(32);
            printerParser.format(context, buf);
            appendable.append(buf);
            }
            } catch (IOException ex) {
            throw new DateTimeException(ex.getMessage(), ex);
            }
            }


            JDK8处理日期时间常用方法

              package com.example.datedemo;


              import java.time.Duration;
              import java.time.LocalDate;
              import java.time.LocalDateTime;
              import java.time.format.DateTimeFormatter;


              /**
               * JDK8之前处理时间的API:SimpleDateFormat,Calendar,java.util.date是非线程安全的,日期/时间处理麻烦
               * JDK8处理时间包 java.time,核心类 LocalDate,LocalTime,Localdatetime
               * DateJDK8.java
               * @author twotwoseven
               * 2019年12月30日
               */
              public class DateJDK8 {
              /**
               * 日期时间格式化
               * JDK8之前:SimpleDateFormat处理格式化,非线程安全的
               * JDK8: DateTimeFormatter 线程安全的日期与时间
               * @return
               */
              public static String getDate(String StrFormat){
              LocalDateTime localDateTime = LocalDateTime.now();
              System.out.println(localDateTime);
              DateTimeFormatter dateTimeFormatter= DateTimeFormatter.ofPattern(StrFormat);
              String format = dateTimeFormatter.format(localDateTime);
              System.out.println(format);
              return format;
              }
              /**
               * 获取指定的日期时间对象
               * @return
               */
              public static LocalDateTime getLocalDateTime(){
              LocalDateTime of = LocalDateTime.of(202012121221,21);
              return of;
              }
              /**
               * 计算日期时间差
               */
              public static void duration(){
              LocalDateTime today = LocalDateTime.now();
              System.out.println(today);
              LocalDateTime changeDate=LocalDateTime.of(202011111111,11);
              System.out.println(changeDate);
              Duration between = Duration.between(today, changeDate);
              System.out.println(between.toDays());//相差天数
              System.out.println(between.toHours());//相差小时
              System.out.println(between.toMinutes());//相差分钟
              System.out.println(between.toMillis());//相差秒
              }


              /**
               * 测试
               * @param args
               */
              public static void main(String[] args) {
              LocalDate now = LocalDate.now();
              System.out.println(now.getYear());
              System.out.println(now.getDayOfWeek());
              System.out.println("-----------------");
              String date = DateJDK8.getDate("yyyy-MM-dd HH:mm:ss");
              System.out.println(date);
              System.out.println("-----------------");
              System.out.println(DateJDK8.getLocalDateTime());
              System.out.println("-----------------");
              DateJDK8.duration();
              }
              }




              文章转载自227decision,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论