Change from: Why is LocalDateTime recommended instead of Date?
By reading this article you will learn:
-
Why do I need LocalDate, LocalTime and LocalDateTime
-
How to use java8's new time API, including creation, formatting, parsing, calculation and modification
Why LocalDate, LocalTime and LocalDateTime are needed
Date if not formatted, the printed date is not readable
Tue Sep 10 09:34:04 CST 2019
Use SimpleDateFormat to format the time, but SimpleDateFormat is the final calling code of the format method of SimpleDateFormat which is not thread safe:
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 is a shared variable, and this shared variable is not under thread safety control. When multiple threads use the same SimpleDateFormat object (such as SimpleDateFormat decorated with static) to call the format method at the same time, multiple threads will call the calendar.setTime method at the same time. It is possible that one thread has just set the time value and another thread will immediately change the set time value to modify the returned format time, which may be wrong. When using SimpleDateFormat in multiple concurrent situations, it should be noted that SimpleDateFormat is not thread safe except for format, and parse method is thread unsafe. The parse method actually calls the alb.establish(calendar).getTime() method to parse, and the alb.establish(calendar) method mainly completes
-
Reset attribute value of date object cal
-
Set cal using the attribute in calb
-
Return the set cal object
But these three steps are not atomic operations
How to ensure thread safety in multithreading concurrency - avoid sharing a SimpleDateFormat object among threads, and create a SimpleDateFormat object once when each thread is used = > the cost of creating and destroying objects is large - lock the places where format and parse methods are used = > poor thread blocking performance - use ThreadLocal to ensure that each thread can create a simpledateform at most once At object = > a better method
Date is troublesome to process time. For example, if you want to get the time of a year, a month, a week, or n days later, it's too difficult to process it with date. You may say that the date class has getYear and getMonth methods. It's Easy to get the date, but they are all discarded
Using java8's new date and time API together
LocalDate
Only date
-
Create LocalDate
//Get current date LocalDate localDate = LocalDate.now(); //Date of construction LocalDate localDate1 = LocalDate.of(2019, 9, 10);
-
Get year, month, day, 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);
LocalTime
Only a few minutes and seconds
-
Create LocalTime
LocalTime localTime = LocalTime.of(13, 51, 10); LocalTime localTime1 = LocalTime.now();
-
Get time, minute and second
//Acquisition hours int hour = localTime.getHour(); int hour1 = localTime.get(ChronoField.HOUR_OF_DAY); //Acquisition score 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);
LocalDateTime
Get month, day, hour, minute and 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);
-
Get LocalDate
LocalDate localDate2 = localDateTime.toLocalDate();
-
Get LocalTime
LocalTime localTime2 = localDateTime.toLocalTime();
Instant
Get seconds
-
Create an Instant object
Instant instant = Instant.now();
-
Get seconds
long currentSecond = instant.getEpochSecond();
-
Get milliseconds
long currentMilli = instant.toEpochMilli();
I think it's more convenient to use System.currentTimeMillis() if it's just to get seconds or milliseconds
Modify LocalDate, LocalTime, LocalDateTime, Instant
LocalDate, LocalTime, LocalDateTime, and Instant are immutable objects. Modifying these object objects will return a copy
-
Increase or decrease the number of juveniles, months, days, etc. take LocalDateTime as an example
LocalDateTime localDateTime = LocalDateTime.of(2019, Month.SEPTEMBER, 10,14, 46, 56); //Increase for one year localDateTime = localDateTime.plusYears(1); localDateTime = localDateTime.plus(1, ChronoUnit.YEARS); //Decrease by one month localDateTime = localDateTime.minusMonths(1); localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);
-
Modify some values with
//Revised to 2019 localDateTime = localDateTime.withYear(2020); //Revised to 2022 localDateTime = localDateTime.with(ChronoField.YEAR, 2022);
You can also modify the month and day
Time calculation
For example, if you want to know the last day of this month and the next weekend, you can get the answer quickly through the time and date API provided
LocalDate localDate = LocalDate.now(); LocalDate localDate1 = localDate.with(firstDayOfYear())
For example, the first day of the current date is returned through firstDayOfYear(). There are many other methods that are not illustrated here
Format 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)
DateTimeFormatter provides multiple formatting methods by default. If the default cannot meet the requirements, you can create a custom formatting method through the ofPattern method of DateTimeFormatter
Analytical time
LocalDate localDate1 = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE); LocalDate localDate2 = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE)
DateTimeFormatter is thread safe compared to SimpleDateFormat
Summary
LocalDateTime: I have all the dates, and I have none of the dates. Please pick me for the Date selection
Application of LocalDateTime in SpringBoot
-
Return the LocalDateTime field to the front end as a time stamp to add a date conversion class
Return the LocalDateTime field to the front end as a time stamp to 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()); } }
And add @ JsonSerialize(using=LocalDateTimeConverter.class) annotation on the LocalDateTime field, as follows:
@JsonSerialize(using = LocalDateTimeConverter.class) protected LocalDateTime gmtModified;
-
Return the LocalDateTime field to the front end by specifying the format date. Add @ jsonformat (shape = jsonformat. Shape. String, pattern = "yyyy MM DD HH: mm: SS") annotation to the LocalDateTime field, as follows:
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") protected LocalDateTime gmtModified;
-
Format the date passed in from the front end and add @ datetimeformat (pattern = "yyyy MM DD HH: mm: SS") annotation on the local datetime field, as follows:
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") protected LocalDateTime gmtModified;