Сводка каждого класса времени в java суммирует Date, Instant и LocalDateTime

Java

Эта статья в основном представляет и сравнивает использование Date, Calendar, Instant, LocalDate, LocalTime и LocalDateTime, а также сравнивает и представляет simpleDateFormat и simpleDateFormat. Более длинные страницы можно выборочно читать для определенных модулей.

1. Дата

Наиболее распространенной операцией для типа Date должна быть новая Date().

 public static void main(String[] args) {
    System.out.println(new Date());
  }

В это время мы получим поле типа Дата текущего времени.Выходной текстTue Jun 09 19:20:37 CST 2020Время с годом, месяцем, днем, часом, минутой и секундой, в котором CST можно рассматривать как стандартное время США, Австралии, Кубы или Китая, а здесь стандартное время Китая. Конечно, наш подход ко времени в этом формате сквозной.java.text.SimpleDateFormatкласс для форматирования и возврата на страницу для отображения

private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  public static void main(String[] args) {
    System.out.println(simpleDateFormat.format(new Date()));
  }

Выход2020-06-09 19:43:21Это результат форматирования поля времени, с которым мы лучше всего знакомы. Конечно, дружеское напоминание здесь заключается в том, чтоSimpleDateFormatЭтот класс не является потокобезопасным, и его следует использовать с осторожностью в сценариях с высокой степенью параллелизма. Тип Date имеет множество следующих функций:

Можно обнаружить, что многие из них стали устаревшими функциями.Хотя их все еще можно использовать, они не гарантируют возможность удаления в будущем обновлении.Мы не рекомендуем использовать такие устаревшие функции. В этот моментjava.util.CalendarХороший класс может помочь нам решить многие проблемы.

Я считаю, что мелкие партнеры, впервые соприкоснувшиеся с java, должны бытьCalendarСила класса была завоевана, но спустя долгое время мы обнаружим, что этот класс не так силен, как представлялось, во-первых, он не поддерживает часовые пояса, а во-вторых, он не потокобезопасен, поэтому учитывая его различные дефекты, java8 использует новый API времени и датыLocalDateTime

2. Мгновенное

InstantПредставляет точку на временной шкале, то есть момент, который можно комбинировать сDateсделать сравнение. Более прямое отличие состоит в том, чтоInstantчто получаетсяUTCвремя иDateЭто текущее время, полученное в соответствии с часовым поясом по умолчанию среды, в которой находится текущий сервер.

//Date
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = new Date();
    System.out.println("new Date() = "+date);
    String s = simpleDateFormat.format(date);
    System.out.println("SimpleDateFormat 格式化Date后 = "+s);

    //Instant
    Instant instant = Instant.now();
    System.out.println("Instant = "+instant);
    System.out.println("Instant +08:00 = "+instant.atOffset(ZoneOffset.ofHours(8)));

выход

new Date() = Wed Jun 10 15:27:48 CST 2020
SimpleDateFormat 格式化Date后 = 2020-06-10 15:27:48
Instant = 2020-06-10T07:27:48.198Z
Instant +08:00 = 2020-06-10T15:27:48.198+08:00

Часовой пояс по умолчаниюUTCВ использованииInstantЭто момент, который требует внимания, а также момент, который легко игнорировать.сосредоточиться здесь! такая же проблема вLocalDate,LocalTimeа такжеLocalDateTimeне существует. ноInstantСогласно официальному описанию, это неизменяемый и потокобезопасный класс.

 * @implSpec
 * This class is immutable and thread-safe.
 *
 * @since 1.8
 */
public final class Instant implements Temporal, TemporalAdjuster, Comparable<Instant>, Serializable {}

Допустимый диапазон времени от-1000000000-01-01T00:00Z~-1000000000-01-01T00:00Z, который может решить проблемы в реальном времени в большинстве сценариев. В то же время в java8 предусмотрено два метода toInsatant() и from() дляDateа такжеInstantПреобразование туда и обратно между

    System.out.println("toInstant() = "+date.toInstant());
    System.out.println("from() = "+Date.from(instant));

выход

toInstant() = 2020-06-10T07:45:42.440Z
from() = Wed Jun 10 15:45:42 CST 2020

Видно, что проблема часового пояса в процессе взаимного преобразования не нуждается в нашем рассмотрении, автоматически будет +08:00 или -08:00. Одна из наиболее неприятных вещей заключается в том, что java8 не нацеленInstantПредоставьте настраиваемый класс форматирования, поэтому мое решение здесь состоит в том, чтобы преобразовать вLocalDateTime, повторное использованиеDateTimeFormatterдля завершения форматирования.

System.out.println("Instant = " + LocalDateTime.ofInstant(instant, ZoneId.systemDefault())
        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

выход

Instant = 2020-06-10 16:02:26

Таким образом, проще решить проблему форматирования.Конечно, вы также можете настроить @config для завершения сопоставленияInstantФорматирование также является универсальным решением.LocalDateTimeа такжеDateTimeFormatterПодробно он будет представлен в следующем содержании.

объяснениеLocalDateTimeПрежде чем мы представим LocalDate и LocalTime соответственно, чтобы мы могли глубже понятьLocalDateTime.

3. LocalDate и LocalTime

(1) LocalDate

LocalDateПервый — это неизменяемый класс с форматом по умолчаниюyyyy-MM-dd, а во-вторых, это класс, который получает только год, месяц и день.Фокус больше на календаре, чем на времени (здесь нам нужно различать два понятия календаря и времени). использоватьLocalDate.now()Вы можете получить текущий год, месяц и дату, или вы можете использоватьLocalDate.of(year,month,dayOfMonth)указать дату

  public static void main(String[] args) {
    LocalDate today = LocalDate.now();
    System.out.println("LocalDate.now() = "+today);
    today = LocalDate.of(2020,06,10);
    LocalDate laterDate = today.plusDays(30);
    System.out.println("LocalDate.of() = "+today.toString());
    System.out.println("plusDays = "+laterDate.toString());
    System.out.println("new Date() = "+ new Date());
  }

вывод:

LocalDate.now() = 2020-06-09
LocalDate.of() = 2020-06-10
plusDays = 2020-07-10
new Date() = Tue Jun 09 20:31:22 CST 2020

Из этого примера мы можем увидеть разницу между LocalDate и Date. в то же время как访问器方法,LocalDateКаждый раз, когда создается новый объект, вместо изменения значения исходного объекта его можно изменить сtoday.plusDays(30)легко увидеть в. Похожий на更改器方法, еще один класс в более ранних версиях javajava.util.GregorianCalendar

  public static void main(String[] args) {
    GregorianCalendar someDay = new GregorianCalendar(2020,06,9);
    System.out.println("before someDay = "+someDay.getTime());
    someDay.add(Calendar.DAY_OF_MONTH,30);
    System.out.println("after someDay = "+someDay.getTime());
  }

выход

before someDay = Thu Jul 09 00:00:00 CST 2020
after someDay = Sat Aug 08 00:00:00 CST 2020

Вы можете видеть, что значение someDay зависит от функцииaddВызов всегда меняется, что согласуется сLocalDateЭто большая разница, и на это стоит обратить внимание.

Еще один момент, который следует отметить здесь, заключается в том, чтоlocalDate.getDayOfWeek().getValue(),LocalDateДля недельного подсчета иCalendarчто-то другое,LocalDateНеделя считается с понедельника, соответствующее значение равно 1, а значение, соответствующее концу воскресенья, равно 7, иCalendarНеделя считается с воскресенья, соответствующее значение равно 1, а значение, соответствующее концу субботы, равно 7. Для сравнения, я лично думаюLocalDateБолее разумный и простой в использовании.

LocalDateОбычно используются следующие методы:

Изображение из тома 2 базовой технологии Java

(2) LocalTime

LocalTimeа такжеLocalDateАналогично — это также неизменяемый класс, формат по умолчанию — ЧЧ:мм:сс.ззз, вы можете видеть, что он фокусируется на текущем моменте.

  public static void main(String[] args) {
    LocalTime localTime = LocalTime.now();
    System.out.println("LocalTime.now() = "+localTime);
    localTime = LocalTime.of(8,8,8,888);
    System.out.println("LocalTime.of() = "+localTime);
    LocalTime laterTime = localTime.plusHours(2);
    System.out.println("localTime.plusHours() = "+laterTime);
    //根据时区获取当前时刻,同理适用与LocalDate
    LocalTime newlocalTime = LocalTime.now(ZoneId.of("America/New_York"));
    System.out.println("America/New_York Time = "+newlocalTime);
  }

выход

LocalTime.now() = 20:58:54.941
LocalTime.of() = 08:08:08.000000888
localTime.plusHours() = 10:08:08.000000888
America/New_York Time = 08:58:54.944

Здесь мы обнаружим, что хотяLocalTimeФормат по умолчанию — ЧЧ:мм:сс.zzz, но он также может поддерживать точность в наносекундах.08:08:08.000000888.LocalTimeОбычно используются следующие методы:

Изображение из тома 2 базовой технологии Java

4. Местная дата и время

через паруLocalDateа такжеLocalTimeвведение,LocalDateTimeДумаю, все уже знают, как им пользоваться. такой же,LocalDateTimeтакже является неизменяемым классом и потокобезопасным, его формат по умолчаниюyyyy-MM-ddTHH:mm:ss.zzz, Очевидно, что в ежедневном процессе веб-разработки мы будем форматировать такой формат даты, о чем я хочу здесь упомянуть.

мы говорили об этом раньшеjava.text.SimpleDateFormatВы можете настроить форматированный формат времени, но это не потокобезопасный класс, поэтому java8 начинает сотрудничатьLocalDateTimeпри условииjava.time.format.DateTimeFormatterисправить эту проблему.

 * @implSpec
 * This class is immutable and thread-safe.
 *
 * @since 1.8
 */
public final class DateTimeFormatter

Это официальное введение в него, этот класс является неизменяемым и потокобезопасным. Так что мы можем использовать его с уверенностью, но дружеское напоминаниеБезопасность потока + безопасность потока не обязательно безопасность потока, не поймите неправильно, мы не будем обсуждать это здесь. Ниже мы иSimpleDateFormatИспользуйте их для сравнения.

    // LocalDateTime
    LocalDateTime localDateTime = LocalDateTime.now();
    String newLocalDateTime = localDateTime.format(DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm:ss"));
    System.out.println("LocalDateTime =  "+localDateTime);
    System.out.println("DateTimeFormatter 格式化后的时间 = "+newLocalDateTime);

    //Date
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = new Date();
    System.out.println("new Date() = "+date);
    String s = simpleDateFormat.format(date);
    System.out.println("SimpleDateFormat 格式化Date后 = "+s);

выход

LocalDateTime =  2020-06-10T14:41:02.546
DateTimeFormatter 格式化后的时间 = 2020-06-10 14:41:02
new Date() = Wed Jun 10 14:41:02 CST 2020
SimpleDateFormat 格式化Date后 = 2020-06-10 14:41:02

Это видно по количеству кодаDateTimeFormatterПреимущество в том, что одна линия выполнена, сравнитеSimpleDateFormatКаждый раз, когда объект должен быть новым, в крайних случаях будет создаваться много экземпляров, которые невозможно переработать за короткое время, и много места в памяти будет потрачено впустую.Конечно, мы также можем использовать статические переменные, добавивsynchronizedдля достижения своей цели, но неизбежной проблемой синхронизированных блоков является блокировка.

Конечно, вы должны сказать, что я могу использовать ThreadLocal для создания копии для решенияSimpleDateFormatвопросы безопасности потоков. Это лучшее решение, а именно:

  private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
      return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }
  };
System.out.println("ThreadLocal = "+threadLocal.get().format(date));

выход

ThreadLocal = 2020-06-10 14:52:05

Очевидно, что результат в порядке, но использованиеLocalDateTime.format(DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm:ss"))Ее можно решить в одну строку, условно говоря, так будет лаконичнее и удобнее, поэтому рекомендуется использоватьDateTimeFormatter.