SimpleDateFormat (SimpleDateFormat) is a format that is static and SimpleDateFormat is not allowed

By reading this article you will learn:

  • Why is it neededLocalDate,LocalTime,LocalDateTime[new classes provided in java8]
  • java8The new timeAPI, including creating, formatting, parsing, calculating, and modifying

Why LocalDate, LocalTime, LocalDateTime

  • Date If no format is used, the printed Date is not readable

    Tue Sep 10 09:34:04 CST 2019
    Copy the code
  • Time is formatted using SimpleDateFormat, but SimpleDateFormat is thread-safe. The format method of SimpleDateFormat finally calls the code:

    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;
        }
    Copy the code

    Calendar is a shared variable, and this shared variable has no thread-safe control. When the format method is called by multiple threads using the same SimpleDateFormat object, the calendar. SetTime method is called by multiple threads simultaneously. It is possible that one thread has just set the time value and another thread changes the time value so that the formatting time returned may be incorrect. Using SimpleDateFormat in multi-concurrent situations requires special attention. In addition to the fact that SimpleDateFormat is thread-unsafe, the parse method is thread-unsafe as well. The parse method actually calls alb.establish(calendar).getTime() to parse, which is mostly done in the alb.establish(calendar) method

      1. Resets the attribute value of the date object CAL
      1. Set the CAL using the properties in calB
      1. Returns the set CAL object

But these three steps are not atomic operations

How can multithreading concurrency be thread safe – avoid sharing a SimpleDateFormat object between threads, SimpleDateFormat objects are created once for each thread that uses them => High overhead of creating and destroying objects – Locking where format and parse methods are used => Poor thread blocking performance – Better to use ThreadLocal to ensure that each thread creates a SimpleDateFormat object at most once

  • DateTime processing is cumbersome, such as wanting to get the year, month, week, andnDays later, if usedDateIt’s too hard to deal with, you might sayDateClass is notgetYear,getMonthThese methods, get year month day veryEasyBut they were abandoned

Come On uses java8’s new date and time API together

LocalDate

It only gets the year, month and day

  • Create a LocalDate

    // Get the current LocalDatelocalDate = LocalDate.now(); // Construct the specified LocalDatelocalDate1 = LocalDate.of(2019, 9, 10);
    Copy the code
  • Gets the year, month, day, and day of the week

    int year = localDate.getYear();
    int year1 = localDate.get(ChronoField.YEAR);
    Month month = localDate.getMonth();
    int month1 = localDate.get(ChronoField.MONTH_OF_YEAR);
    int day = localDate.getDayOfMonth();
    int day1 = localDate.get(ChronoField.DAY_OF_MONTH);
    DayOfWeek dayOfWeek = localDate.getDayOfWeek();
    int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);
    Copy the code
LocalTime

It only takes a few minutes, a few seconds

  • Create a LocalTime

     LocalTime localTime = LocalTime.of(13, 51, 10);
     LocalTime localTime1 = LocalTime.now();
    Copy the code
  • Get time minute second

    // Get the hour int hour =localTime.getHour();
    int hour1 = localTime.get(ChronoField.HOUR_OF_DAY); // Get minute int minute =localTime.getMinute();
    int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR); // get seconds int second =localTime.getSecond();
    int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
    Copy the code
LocalDateTime

Get year, month, day, hour, minute, second, equal to LocalDate+LocalTime

  • Create LocalDateTime

    LocalDateTime localDateTime = LocalDateTime.now();
    LocalDateTime localDateTime1 = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56);
    LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
    LocalDateTime localDateTime3 = localDate.atTime(localTime);
    LocalDateTime localDateTime4 = localTime.atDate(localDate);
    Copy the code
  • To obtain a LocalDate

     LocalDate localDate2 = localDateTime.toLocalDate();
    Copy the code
  • To obtain a LocalTime

    LocalTime localTime2 = localDateTime.toLocalTime();
    Copy the code
Instant

Get number of seconds

  • Creating Instant Objects

    Instant instant = Instant.now();
    Copy the code
  • Get number of seconds

    long currentSecond = instant.getEpochSecond();
    Copy the code
  • Get milliseconds

    long currentMilli = instant.toEpochMilli();
    Copy the code

I think it’s more convenient to use System.currentTimemillis () if you’re just trying to get seconds or milliseconds

Modify LocalDate, LocalTime, LocalDateTime, and Instant

LocalDate, LocalTime, LocalDateTime, and Instant are immutable objects. Modifying these objects will return a copy

  • Add or subtract years, months, days, etcLocalDateTimeAs an example
    LocalDateTime localDateTime = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56); // Add a yearlocalDateTime = localDateTime.plusYears(1);
    localDateTime = localDateTime.plus(1, ChronoUnit.YEARS); // Reduce by one monthlocalDateTime = localDateTime.minusMonths(1);
    localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);  
    Copy the code
  • throughwithModify some values
    // Change the year to 2019localDateTime = localDateTime.withYear(2020); // Change to 2022localDateTime = localDateTime.with(ChronoField.YEAR, 2022);
    Copy the code

You can also modify the month and day

Time to calculate

For example, when you want to know what day the last day of the month is and what day the next weekend is, the time and date API provides quick answers

LocalDate localDate = LocalDate.now();
LocalDate localDate1 = localDate.with(firstDayOfYear());
Copy the code

For example, firstDayOfYear() returns the first day of the current date, and there are many other methods I won’t illustrate here

Formatting time
LocalDate localDate = LocalDate.of(2019, 9, 10);
String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE); . / / custom formatting DateTimeFormatter DateTimeFormatter = DateTimeFormatter ofPattern ("dd/MM/yyyy");
String s3 = localDate.format(dateTimeFormatter);
Copy the code

The DateTimeFormatter provides a variety of formatting methods by default. If the default formatting method does not meet your requirements, you can use the DateTimeFormatter’s ofPattern method to create a custom formatting method

Parsing time
LocalDate localDate1 = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate localDate2 = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE);
Copy the code

Compared to SimpleDateFormat, DateTimeFormatter is thread-safe

summary

LocalDateTime: LocalDateTime: LocalDateTime: LocalDateTime: LocalDateTime: LocalDateTime: LocalDateTime: LocalDateTime: LocalDateTime: LocalDateTime

====================== Update On 2019/09/18 =================

LocalDateTime is applied to SpringBoot

  • The LocalDateTime field is returned to the front end as a timestamp

    Add a date conversion class
    public class LocalDateTimeConverter extends JsonSerializer<LocalDateTime> {
    
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeNumber(value.toInstant(ZoneOffset.of("+ 8")).toEpochMilli()); }}Copy the code

    And in theLocalDateTimeAdd to field@JsonSerialize(using = LocalDateTimeConverter.class)Notes, as follows:

    @JsonSerialize(using = LocalDateTimeConverter.class)
    protected LocalDateTime gmtModified;
    Copy the code
  • The LocalDateTime field is returned to the front end with a formatted date specified

    LocalDateTimeAdd to field@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")Just a note, as follows:
    @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
    protected LocalDateTime gmtModified;
    Copy the code
  • Format the date passed in by the front end

    LocalDateTimeAdd to field@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")Just a note, as follows:
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    protected LocalDateTime gmtModified;
    Copy the code