• LocalDate和localDateTime常用方法


    public class TestTime extends TestCase {
        private static final Logger log = LoggerFactory.getLogger(TestLocalDate.class);
        public void testDate() {
            //创建LocalDate,只会获取年月日
            //获取当前年月日
            LocalDate localDate = LocalDate.now();
            //构造指定的年月日
            LocalDate specifiedDate = LocalDate.of(2019, 2, 19);
            //年
            int year = specifiedDate.getYear(); //2019
            int year1 = specifiedDate.get(ChronoField.YEAR); //2019
            //月
            Month month = specifiedDate.getMonth();  //FEBRUARY
            int month1 = specifiedDate.get(ChronoField.MONTH_OF_YEAR); //2
            //日
            int day = specifiedDate.getDayOfMonth(); //19
            int day1 = specifiedDate.get(ChronoField.DAY_OF_MONTH); //19
            //星期几
            DayOfWeek dayOfWeek = specifiedDate.getDayOfWeek(); //TUESDAY
            int dayOfWeek1 = specifiedDate.get(ChronoField.DAY_OF_WEEK); //2
    
            //创建LocalTime,只会获取几时几分几秒
            LocalTime localTime = LocalTime.now();
            //构造指定LocalTime
            LocalTime specifiedTime = LocalTime.of(8, 18, 28);
            //获取小时
            int hour = specifiedTime.getHour(); //8
            int hour1 = specifiedTime.get(ChronoField.HOUR_OF_DAY);  //8
            //获取分
            int minute = specifiedTime.getMinute(); //18
            int minute1 = specifiedTime.get(ChronoField.MINUTE_OF_HOUR); //18
    
            //创建LocalDateTime,获取年月日时分秒,等于LocalDate+LocalTime
            LocalDateTime localDateTime = LocalDateTime.now(); //now
            LocalDateTime specifiedTimeLocalDateTime = LocalDateTime.of(2019, Month.FEBRUARY, 19, 8, 18, 28); //2019-02-19T08:18:28
            LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime); //now
            LocalDateTime localDateTime3 = localDate.atTime(localTime); //now
            LocalDateTime localDateTime4 = localTime.atDate(localDate); //now
    
            log.info("{},{},{},{},{}", localDateTime, specifiedTimeLocalDateTime, localDateTime2, localDateTime3, localDateTime4);
            //获取LocalDate
            specifiedTimeLocalDateTime.toLocalDate(); //2019-02-19
            //获取LocalTime
            specifiedTimeLocalDateTime.toLocalTime(); //08:18:28
    
            //创建 Instant 对象 是不带时区的即时时间点
            Instant instant = Instant.now(); //2020-04-23T06:58:21.651Z
            //获取秒数
            long currentSecond = instant.getEpochSecond(); //1587625101
            //获取毫秒数
            long currentMilli = instant.toEpochMilli(); //1587625101651
    
            //修改LocalDate、LocalTime、LocalDateTime、Instant
            //LocalDate 、 LocalTime 、 LocalDateTime 、 Instant 为不可变对象,修改这些对象对象会返回一个副本
            LocalDateTime localDateTime5 = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56); //2019-09-10T14:46:56
            //增加一年
            localDateTime5 = localDateTime5.plusYears(1); //2020-09-10T14:46:56
            localDateTime5 = localDateTime5.plus(1, ChronoUnit.YEARS); //2021-09-10T14:46:56
            //减少一个月
            localDateTime5 = localDateTime5.minusMonths(1); //2021-08-10T14:46:56
            localDateTime5 = localDateTime5.minus(1, ChronoUnit.MONTHS); //2021-07-10T14:46:56
    
            //通过with修改某些值
            //修改年为2020
            localDateTime = localDateTime.withYear(2020); //2020-04-23T15:00:55.751
            //修改为2022
            localDateTime = localDateTime.with(ChronoField.YEAR, 2022); //2022-04-23T15:00:55.751
    
            //时间计算
            //比如有些时候想知道这个月的最后一天是几号、下个周末是几号,通过提供的时间和日期API可以很快得到答案
            LocalDate localDate3 = LocalDate.now();
            //第一天
            LocalDate f = localDate3.with(firstDayOfMonth());   //2020-04-01
    
            //格式化时间
            LocalDate localDate4 = LocalDate.of(2019, 9, 10);
            String s1 = localDate4.format(DateTimeFormatter.BASIC_ISO_DATE);   //20190910
            String s2 = localDate4.format(DateTimeFormatter.ISO_LOCAL_DATE);   //2019-09-10
    
            String s = localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE); //2022-04-23
    
            //DateTimeFormatter 默认提供了多种格式化方式,如果默认提供的不能满足要求,可以通过
            //DateTimeFormatter 的 ofPattern 方法创建自定义格式化方式
            String s3 = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm")); //2022-04-23 03:00
    
            //解析时间
            LocalDate localDate5 = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE);  //2019-09-10
            LocalDate localDate6 = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE); //2019-09-10
        }
    }
    

    项目应用LocalDateTime

    • 将LocalDateTime字段以时间戳的方式返回给前端

    添加日期转化类

    public class LocalDateTimeConverter extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializer) throws IOException {
            gen.writeNumber(value.toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
    }
    

    并在 LocalDateTime 字段上添加 @JsonSerialize(using = LocalDateTimeConverter.class) 注解,
    如下:

        @JsonSerialize(using = LocalDateTimeConverter.class)
        private LocalDateTime day;
    
    • 将LocalDateTime字段以指定格式化日期的方式返回给前端

    在 LocalDateTime 字段上添加 @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") 注解即可,如下:

        @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
        private LocalDateTime register;
    
    • 对前端传入的日期进行格式化

    在 LocalDateTime 字段上添加 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") 注解即可,如下:

        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime login;
    

    与原来Date类对比优势

    • Date如果不格式化,打印出的日期可读性差
    • 使用SimpleDateFormat对时间进行格式化,但SimpleDateFormat是线程不安全的

    SimpleDateFormatformat方法最终调用代码:

    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;
        }
    
      可以看到,calendar是共享变量,并且这个共享变量没有做线程安全控制。当多个线程同时使用相同的SimpleDateFormat对象【如用static修饰的SimpleDateFormat】调用format方法时,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。在多并发情况下使用SimpleDateFormat需格外注意SimpleDateFormat除了format是线程不安全以外,parse方法也是线程不安全的。parse方法实际调用alb.establish(calendar).getTime()方法来解析,alb.establish(calendar)方法里主要完成了:
    1. 重置日期对象cal的属性值
    2. 使用calb中中属性设置cal
    3. 返回设置好的cal对象

    但是这三步不是原子操作

      多线程并发如何保证线程安全 - 避免线程之间共享一个SimpleDateFormat对象,每个线程使用时都创建一次SimpleDateFormat对象 => 创建和销毁对象的开销大 - 对使用formatparse方法的地方进行加锁 => 线程阻塞性能差 - 使用ThreadLocal保证每个线程最多只创建一次SimpleDateFormat对象 => 较好的方法

    • Date对时间处理比较麻烦,比如想获取某年、某月、某星期,以及n天以后的时间,如果用Date来处理是很麻烦的,虽然Date类有getYeargetMonth这些方但都已经被弃用

    原文

  • 相关阅读:
    基于摸板匹配的目標跟蹤算法
    spoj 2713 Can you answer these queries IV
    zoj 3633 Alice's present
    hdu 3642 Get The Treasury
    poj 1195 Mobile phones
    poj 2760 End of Windless Days
    zoj 3540 Adding New Machine
    spoj 1716 Can you answer these queries III
    spoj 1043 Can you answer these queries I
    spoj 2916 Can you answer these queries V
  • 原文地址:https://www.cnblogs.com/sueyyyy/p/12838312.html
Copyright © 2020-2023  润新知