Обработка времени часто встречается в процессе разработки проекта, но правильно ли вы ее используете, понимаете ли, что статическая модификация 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
Только получить несколько минут и несколько секунд
-
Создайте
LocalTimeLocalTime 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
-
Создайте
LocalDateTimeLocalDateTime 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); -
Получать
LocalDateLocalDate localDate2 = localDateTime.toLocalDate(); -
Получать
LocalTimeLocalTime 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;