Skip to content

时间类型

Date时间类型

使用java.util.Date类来处理日期时间,存在比如可变性、线程安全性和时区支持的不足

  • getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数(时间戳
  • setTime(long time):设置日期对象的时间,以毫秒为单位
  • before(Date when)after(Date when):用于比较日期的先后顺序
  • equals(Object obj):用于比较两个日期是否相等
  • toString():返回日期的字符串表示
  • compareTo(Date anotherDate):比较两个日期的顺序
  • clone():克隆日期对象
  • toInstant():将日期对象转换为 java.time.Instant 对象,适用于 Java 8 之后的时间处理
java
        String dateString = "2023-07-12T12:18:12";
        // 使用SimpleDateFormat进行字符串和日期格式的转换
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        try {
            // parse方法将字符串转换为Date类型的时间
            Date date = dateFormat.parse(dateString);
            // Wed Jul 12 12:18:12 CST 2023
            System.out.println(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

SimpleDateFormat 是 Java 中用于格式化和解析日期时间的类。它可以根据指定的模式将日期时间对象转换为字符串,或者将字符串解析为日期时间对象。SimpleDateFormat 类并不是线程安全的,推荐使用 java.time.format.DateTimeFormatter 类来进行日期时间的格式化和解析

Calender日历对象

  • get(int field):获取指定字段的值,比如获取年份、月份、日期等
  • set(int field, int value):设置指定字段的值,比如设置年份、月份、日期等
  • add(int field, int amount):根据日历的规则,将指定的时间量添加到给定的日历字段中
  • getTime():返回一个表示此 Calendar 时间值的 Date 对象
  • setTime(Date date):用给定的 Date 设置此 Calendar 的时间
  • getActualMaximum(int field):获取指定字段的最大值,比如获取当月的最大日期数
  • getActualMinimum(int field):获取指定字段的最小值,比如获取当月的最小日期数
java
    /**
     * 获取到当月月末时间
     *
     * @param date 传入的日期
     * @return 返回当月月末时间
     */
    private Date getEndOfMonth(Date date) {
        // 创建一个日历对象
        Calendar calendar = Calendar.getInstance();
        // 将传入的日期设置为日历对象的时间
        calendar.setTime(date);
        // Calendar.DAY_OF_MONTH 是一个表示日历字段的枚举常量,它代表了月份中的某一天,这里将日历对象的日期设置为当月的最大日期(即月末日期)
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        // 返回当月月末日期所对应的Date对象
        return calendar.getTime();
    }

SimpleDateFormat格式化

代表简单日期格式化,可以用来把日期对象、时间毫秒值格式化成想要的格式

  • parse():将字符串转换为Date类型的时间
  • format():将时间类型格式化为字符串
java
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
        String format = dateFormat.format(date);
        // 2024年01月01日 13:10:32 星期一 下午
        System.out.println(format);

Java 8中的新日期时间类

  • 代替Calendar
    • LocalDate:年、月、日
    • LocalTime:时、分、秒
    • LocalDateTime:年、月、日 时、分、秒
    • ZoneId:时区
    • ZonedDateTime:带时区的时间
  • 代替Date
    • Instant:时间戳/时间线
  • 代替SimpleDateFormat
    • DateTimeFormatter:用于时间的格式化和解析
  • 其它补充
    • Period:时间间隔(年、月、日)Period.of(1, 2, 3); // 代表1年2个月3天的时间间隔
    • Duration:时间间隔(时、分、秒、纳秒)Duration.of(5, ChronoUnit.HOURS); // 代表5小时的持续时间,使用 ChronoUnit 枚举指定时间单位

java.time.LocalDate

java.time.LocalDate是Java 8中引入的日期类,它表示ISO-8601日历系统中的日期,不包含时间部分。它是不可变的、线程安全的,并且提供了丰富的日期操作方法

  • now():获取当前的日期
  • of(int year, int month, int dayOfMonth):根据指定的年、月、日创建一个LocalDate实例
  • getYear()、getMonthValue()、getDayOfMonth():分别获取年、月、日的值
  • plusDays(long daysToAdd)、minusDays(long daysToSubtract):分别增加或减少指定天数
  • isBefore(LocalDate other)、isAfter(LocalDate other):判断是否在另一个日期之前或之后
  • with(TemporalAdjuster adjuster):应用指定的调整器来调整日期,比如将日期调整到下一个工作日
java
        String dateString = "2023-07-12";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(dateString, formatter);
        // 2023-07-12
        System.out.println(date);

LocalDate类进行转换

返回任意月的月末日期对象:

java
    public static LocalDate getLastDayOfMonth(LocalDate date) {
        return date.with(TemporalAdjusters.lastDayOfMonth());
    }

java.time.LocalDateTime

Java 8中引入的日期时间类,它表示ISO-8601日历系统中的日期和时间,但不包含时区信息。它同样是不可变的、线程安全的,并且提供了丰富的日期时间操作方法

  • now():获取当前的日期时间
  • of(int year, int month, int dayOfMonth, int hour, int minute):根据指定的年、月、日、时、分创建一个LocalDateTime实例
  • getYear()getMonthValue()getDayOfMonth()getHour()getMinute():分别获取年、月、日、时、分的值
  • plusDays(long daysToAdd)minusDays(long daysToSubtract)plusHours(long hoursToAdd):分别增加或减少指定天数或小时数
  • isBefore(LocalDateTime other)、isAfter(LocalDateTime other):判断是否在另一个日期时间之前或之后
  • with(TemporalAdjuster adjuster):应用指定的调整器来调整日期时间,比如将时间调整到下一个小时
java
        // Z表示零时区
        String dateString = "2023-07-12T12:18:12.102Z";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
        LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);
        // 2023-07-12T12:18:12.102
        System.out.println(dateTime);

LocalDateTime类进行转换

拆分合并

可以将LocalDateTime对象拆分为LocalDate对象和LocalTime对象

java
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDate localDate = localDateTime.toLocalDate();
        LocalTime localTime = localDateTime.toLocalTime();

可以将LocalDate对象和LocalTime对象合并为一个LocalDateTime对象

java
        LocalDate localDate = LocalDate.parse("2023-12-31");
        LocalTime localTime = LocalTime.parse("12:12:12");
        // 调用atTime将localDate和localTime合并为localDateTime1
        LocalDateTime localDateTime1 = localDate.atTime(localTime);
        // 调用atDate将localTime和localDate合并为localDateTime2
        LocalDateTime localDateTime2 = localTime.atDate(localDate);

java.time.format.DateTimeFormatter

替代SimpleDateFormat

  • parse():将字符串转换为LocalDateTime类型的时间
  • format():将时间类型格式化为字符串
java
        String dateString = "2023-07-12T12:18:12";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
        LocalDateTime date = LocalDateTime.parse(dateString, formatter);
        // 2023-07-12T12:18:12
        System.out.println(date);


        LocalDateTime date = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss EEE a");
        String format = formatter.format(date);
        // 2024年01月01日 13:16:26 星期一 下午
        System.out.println(format);

其它时间类

  • java.time.ZonedDateTime:表示带时区的日期时间,可以用于处理时区相关的日期时间操作
  • java.time.OffsetDateTime:表示带有时区偏移的日期时间,适用于需要处理时区和偏移量的情况
  • java.time.Instant:表示时间线上的一个时间点,通常用于处理时间戳等需求
  • java.time.Periodjava.time.Duration:分别用于表示时间段的持续时间和日期之间的间隔,比如处理两个时间点之间的时间差

注解使用

  • @JsonFormat:用于属性上,用于指定日期、时间或数字等类型的格式化方式的注解,通常用于在将Java对象转换为JSON字符串时,对日期、时间等格式进行定制化(@JsonValue用于方法上,指定方法的返回值作为整个对象的JSON表示)

    • pattern:指定日期、时间的格式,例如"yyyy-MM-dd HH:mm:ss"

      • java
            // 指定后端返回的格式,为"yyyy-MM-dd HH:mm:ss",时区为GMT+8
            @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
            private Date createTime;
    • shape:指定日期、时间的序列化形式,有以下几种取值:

      • JsonFormat.Shape.STRING:以字符串形式序列化

        • 设置数字类型的格式化方式,转化为字符串,解决前端精度问题

          • java
                // 指定MVC在序列化为JSON时将该字段转化为String类型
                @JsonFormat(shape = JsonFormat.Shape.STRING)
                private Long id;
      • JsonFormat.Shape.NUMBER:以数字形式序列化

      • JsonFormat.Shape.ARRAY:以数组形式序列化

      • JsonFormat.Shape.OBJECT:以对象形式序列化

    • locale:指定地区信息,用于格式化日期、时间

    • timezone:指定时区信息,用于格式化日期、时间

  • @DateTimeFormat:用于属性上,将接收的字符串转换为日期(只有字符串符合指定格式时才会进行转换),有patterniso属性,两者一起使用时,pattern属性会覆盖iso属性。对于指定的情况不符合时会使用默认的SpringMVC字符串处理方式

    • pattern:指定日期、时间的格式(对于同时存在日期和时间的,字符串中需要通过T来分隔)有以下几种取值:

      • "yyyy-MM-dd":代表年-月-日

      • "yyyy/MM/dd":代表年/月/日

      • "yyyy-MM-dd HH:mm:ss":代表年-月-日 时:分:秒

        • java
              // 指定接收前端字符串的格式
              @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
              private Date date;
      • "yyyy-MM-dd'T'HH:mm:ss":代表年-月-日THH:mm:ss(ISO 8601格式)

    • iso:指定日期、时间的ISO格式,有以下几种取值:

      • DateTimeFormat.ISO.DATE:相当于"yyyy-MM-dd"格式。这表示只包括年、月和日的部分,不包括时间部分

        • java
              // 日期可以使用ISO日期格式,如果想要包含时间,可以使用DateTimeFormat.ISO.DATE_TIME
              @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
              private Date date;
      • DateTimeFormat.ISO.DATE_TIME:指定的是日期和时间的完整格式,即"yyyy-MM-dd'T'HH:mm:ss.SSSX"。这个格式包括年、月、日、时、分、秒以及毫秒,并且还考虑了时区信息("X"为时区信息,它会形如"+08:00"表示东八区)

对于代码,在接收前端数据时,Spring框架会报错,因为两者不一致(但是只用于后端数据返回就不会)

java
       @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
       @DateTimeFormat(pattern = "yyyy-MM-dd")
       private Date visitorDate;

应该修改为,保持一致

java
       @JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
       @DateTimeFormat(pattern = "yyyy-MM-dd")
       private Date visitorDate;