Обработка времени часто встречается в процессе разработки проекта, но правильно ли вы ее используете, понимаете ли, что статическая модификация SimpleDateFormat отключена в руководстве по разработке Alibaba?
Прочитав эту статью, вы узнаете:
- зачем нужно
LocalDate
,LocalTime
,LocalDateTime
[Классы, недавно предоставленные java8] -
java8
Новое времяAPI
использование, включая создание, форматирование, синтаксический анализ, вычисление, изменение
Зачем вам LocalDate, LocalTime, LocalDateTime
-
Date
Без форматирования напечатанная дата плохо читаетсяTue Sep 10 09:34:04 CST 2019
-
использовать
SimpleDateFormat
отформатируйте время, ноSimpleDateFormat
поток небезопасенSimpleDateFormat
изformat
Окончательный код вызова метода: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)
Метод в основном завершен-
- Сбросить значение свойства объекта даты cal
-
- Используйте свойства в calb, чтобы установить cal
-
- Возвращает установленный объект калибровки
-
Но эти три шага не являются атомарными операциями.
Как обеспечить безопасность потоков с помощью многопоточного параллелизма
- Избегайте совместного использования одного между потокамиSimpleDateFormat
объект, созданный один раз для каждого потокаSimpleDateFormat
Объект => создание и уничтожение объектов дорого
- для использованияformat
иparse
Блокировка вместо метода => плохая производительность блокировки потока
- использоватьThreadLocal
Убедитесь, что каждый поток создается не более одного разаSimpleDateFormat
объект => лучший метод
-
Date
Более хлопотно иметь дело со временем, например, желая получить определенный год, определенный месяц, определенную неделю и т. д.n
дней спустя, если вы используетеDate
С этим так трудно иметь дело, вы можете сказатьDate
класс не имеетgetYear
,getMonth
Это методы, очень легко получить год, месяц и деньEasy
, но устарели.
Come On использует новый API даты и времени java8 вместе
LocalDate
Получить только год, месяц и день
-
Создайте
LocalDate
//获取当前年月日 LocalDate localDate = LocalDate.now(); //构造指定的年月日 LocalDate localDate1 = LocalDate.of(2019, 9, 10);
-
Получить год, месяц, день, день недели
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
Только получить несколько минут и несколько секунд
-
Создайте
LocalTime
LocalTime localTime = LocalTime.of(13, 51, 10); LocalTime localTime1 = LocalTime.now();
-
Получить часы, минуты и секунды
//获取小时 int hour = localTime.getHour(); int hour1 = localTime.get(ChronoField.HOUR_OF_DAY); //获取分 int minute = localTime.getMinute(); int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR); //获取秒 int second = localTime.getSecond(); int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
LocalDateTime
Получить год, месяц, день, час, минуту и секунду, что равно LocalDate+LocalTime
-
Создайте
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);
-
Получать
LocalDate
LocalDate localDate2 = localDateTime.toLocalDate();
-
Получать
LocalTime
LocalTime localTime2 = localDateTime.toLocalTime();
Instant
получить секунды
-
Создайте
Instant
объектInstant instant = Instant.now();
-
получить секунды
long currentSecond = instant.getEpochSecond();
-
получить миллисекунды
long currentMilli = instant.toEpochMilli();
Лично я считаю, что если вы просто хотите получить секунды или миллисекунды, используйтеSystem.currentTimeMillis()
более удобно
Изменить LocalDate, LocalTime, LocalDateTime, Instant
LocalDate
,LocalTime
,LocalDateTime
,Instant
занеизменяемый объект, изменение этих объектоввернуть копию
- Увеличение, уменьшение количества лет, месяцев, дней и т.д.
от
LocalDateTime
НапримерLocalDateTime localDateTime = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56); //增加一年 localDateTime = localDateTime.plusYears(1); localDateTime = localDateTime.plus(1, ChronoUnit.YEARS); //减少一个月 localDateTime = localDateTime.minusMonths(1); localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);
- пройти через
with
изменить некоторые значения//修改年为2019 localDateTime = localDateTime.withYear(2020); //修改为2022 localDateTime = localDateTime.with(ChronoField.YEAR, 2022);
Вы также можете изменить месяц и день
расчет времени
Например, иногда вы хотите узнать, какое число является последним днем в этом месяце и какое число будет следующим выходным.Вы можете быстро получить ответ через предоставленный API времени и даты.
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = localDate.with(firstDayOfYear());
например, черезfirstDayOfYear()
Возвращает дату первого дня текущей даты, и существует множество методов, которые здесь не объясняются.
время форматирования
LocalDate localDate = LocalDate.of(2019, 9, 10);
String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
//自定义格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String s3 = localDate.format(dateTimeFormatter);
DateTimeFormatter
По умолчанию предусмотрены различные методы форматирования, если методы по умолчанию не соответствуют требованиям, вы можетеDateTimeFormatter
изofPattern
способ создания пользовательского форматирования
время разбора
LocalDate localDate1 = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate localDate2 = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE);
иSimpleDateFormat
по сравнению с,DateTimeFormatter
является потокобезопасным
резюме
LocalDateTime
:Date
У меня есть несколько,Date
У меня тоже нет, выберите датуPick Me
====================== Update On 2019/09/18 =================
Применение LocalDateTime в SpringBoot
- Верните поле LocalDateTime во внешний интерфейс в виде метки времени.
Добавить класс преобразования даты
И в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()); } }
LocalDateTime
добавить в поле@JsonSerialize(using = LocalDateTimeConverter.class)
Примечания, как показано ниже:@JsonSerialize(using = LocalDateTimeConverter.class) protected LocalDateTime gmtModified;
- Возвращает поле 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") protected LocalDateTime gmtModified;
- Форматировать дату, переданную из внешнего интерфейса
существуетLocalDateTime
добавить в поле@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
Аннотируйте его следующим образом:@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") protected LocalDateTime gmtModified;