编程语言与数据库日期时间存储结构原理及跨端转换机制问询
日期时间存储与跨端转换问题解答
1. 编程语言与数据库的日期时间存储结构运作逻辑
编程语言侧存储逻辑
- 绝大多数编程语言的原生日期时间类型底层都是基于Unix时间戳实现,也就是存储从
1970-01-01 00:00:00 UTC(Unix纪元)开始计算的整数,精度从毫秒、微秒到纳秒不等,比如Python的datetime、Java的Date/LocalDateTime、JavaScript的Date都遵循这个逻辑,上层只封装了时区转换、格式化、时间计算的对外方法。 - 部分语言提供带时区的原生时间类型,会额外存储时区偏移量信息,比如Java的
ZonedDateTime、Go的time.Time,从底层避免跨时区计算出现偏差。
数据库侧存储逻辑
主流数据库的时间类型主要分为两类:
- 无时区感知类型:比如MySQL的
DATETIME、PostgreSQL的timestamp without time zone,底层存储的是时间字符串对应的二进制编码,不会自动做时区转换,写入的值和查询返回的值完全一致,不受会话时区影响。 - 带时区感知类型:比如MySQL的
TIMESTAMP、PostgreSQL的timestamp with time zone,底层实际存储的是UTC标准的Unix时间戳,写入时会自动将会话时区的输入时间转成UTC时间存储,查询时再转成当前会话时区的时间返回。举个实际例子:东八区会话写入2024-05-20 12:00:00到TIMESTAMP字段,底层存的是时间戳1716177600,如果切换到西五区会话查询,返回结果会自动转为2024-05-19 23:00:00。 - 除此之外还有
DATE、TIME等截断型时间类型,存储逻辑和上面一致,只是去掉了不需要的时间/日期部分。
2. 编程语言与数据库之间的时间转换模块
这个转换流程一般由三层组件配合完成,常规场景下不需要手动写转换逻辑:
- 第一层是数据库驱动:也就是项目中引入的对应数据库连接依赖,比如Python的
pymysql/psycopg2、Java的mysql-connector-java、Go的database/sql驱动包,驱动会直接把数据库返回的二进制时间值转换为对应语言的原生日期时间类型,反过来也会把语言侧的时间类型转为数据库可识别的格式传输。 - 第二层是ORM框架(使用ORM的场景下):比如Django ORM、MyBatis、Hibernate、GORM等,会在驱动转换的基础上做二次映射,自动把时间值绑定到实体类的对应字段,也支持自定义转换规则适配特殊的存储格式(比如把时间存为整数时间戳、自定义格式字符串等)。
- 特殊业务场景下序列化工具也会参与转换:比如前后端交互时用的Jackson、Gson、Python json模块,会把语言原生时间类型转为前端需要的字符串格式,或者把前端传入的时间字符串转成原生类型后再写入数据库。
内容的提问来源于stack exchange,提问作者vikben
相关产品推荐
相关产品推荐

