java LocalDateTime 和 mysql datetime timestamp时区问题

  • Post author:
  • Post category:java




1. java 中 LocalDateTime

java 中的 LocalDateTime 是没有时区概念的

获取当前时间时,等于当前UTC时间 + 服务时区偏移

比如当前时间是 2022-05-18T16:09:48.869+08:00[Asia/Shanghai]

那么 LocalDateTime.now() 得到的时间就是 2022-05-18T16:09:48.869

下面是java源码

public static LocalDateTime now(Clock clock) {
        Objects.requireNonNull(clock, "clock");
        final Instant now = clock.instant();  // called once
        ZoneOffset offset = clock.getZone().getRules().getOffset(now);
        return ofEpochSecond(now.getEpochSecond(), now.getNano(), offset);
    }
    public static LocalDateTime ofEpochSecond(long epochSecond, int nanoOfSecond, ZoneOffset offset) {
        Objects.requireNonNull(offset, "offset");
        NANO_OF_SECOND.checkValidValue(nanoOfSecond);
        // 标准时间戳 + 时区的偏移量
        long localSecond = epochSecond + offset.getTotalSeconds();  // overflow caught later
        long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY);
        int secsOfDay = (int)Math.floorMod(localSecond, SECONDS_PER_DAY);
        LocalDate date = LocalDate.ofEpochDay(localEpochDay);
        LocalTime time = LocalTime.ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + nanoOfSecond);
        return new LocalDateTime(date, time);
    }
        @Test
    public void test2() {
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        System.out.println(now.atZone(ZoneId.of(ZoneOffset.UTC.getId())));
        System.out.println(now.atZone(ZoneId.of("+8")));
        System.out.println(DateTimeFormatter.ISO_DATE_TIME.format(now.atZone(ZoneId.of(ZoneOffset.UTC.getId()))));

        Instant now1 = Instant.now();
        System.out.println(now1);
        System.out.println(now1.atZone(ZoneId.systemDefault()));
    }
/* 测试结果
2022-05-18T16:09:48.864
2022-05-18T16:09:48.864Z
2022-05-18T16:09:48.864+08:00
2022-05-18T16:09:48.864Z
2022-05-18T08:09:48.869Z
2022-05-18T16:09:48.869+08:00[Asia/Shanghai]
*/



2. mysql datetime timestamp 时区问题

mysql datetime 是没有时区概念的

取值范围是 ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’

timestamp 是有时区概念的

显示是当前时间,存储是标准时间

CREATE TABLE time_test
(
    id               bigint AUTO_INCREMENT PRIMARY KEY,
    create_datetime  datetime(6) COMMENT '创建时间',
    create_timestamp timestamp(6) COMMENT '创建时间戳'
);
INSERT into time_test(create_datetime, create_timestamp) VALUES (NOW(), current_timestamp());
SELECT * from time_test;
set TIME_ZONE = '+00:00';
SELECT * from time_test;
# 回撤时区修改
set TIME_ZONE = '+08:00';

在这里插入图片描述

在这里插入图片描述



版权声明:本文为qq_22783587原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。