实践:根据时区显示时间

背景

在数据库中存储时间,不会自动对时区进行处理,要想针对不同时区作时间显示的适配,需要在程序中做适配,本文即为解决这一问题的实践案例。

数据库存 UTC 时间

插入记录时,使用 datetime.utcnow()获取当前 utc 时间,并记录到数据库

class File(Base):
    __tablename__ = "tb_file"
    id = Column(Integer, primary_key=True)
    bucket = Column(String)
    uuid = Column(String, unique=True)
    name = Column(String, index=True)
    type = Column(String, index=True)
    url = Column(String)
    # 在 Python 中,int类型理论上可以表示任意大小的整数,仅受限于可用的内存大小
    # 在 MySQL 中,int 数值范围是32 位整数 0~42 9496 7295,而文件大小限制了 4M,够用了
    size = Column(Integer)
    create_stamp = Column(TIMESTAMP, nullable=False, default=datetime.utcnow())
    update_stamp = Column(TIMESTAMP, nullable=False, default=datetime.utcnow())

在数据库中,使用 timestamp 对创建时间和更新时间进行存储

CREATE TABLE `tb_file`
(
    `id`           int          NOT NULL AUTO_INCREMENT COMMENT '文件编码',
    `bucket`       varchar(20)  NOT NULL COMMENT 'minio中的存储桶',
    `uuid`         varchar(64)  NOT NULL COMMENT 'uuid替换',
    `name`         varchar(64)  NOT NULL COMMENT '文件名(包含文件名)',
    `type`         varchar(10)  NOT NULL COMMENT '文件类型',
    `url`          varchar(350) NOT NULL COMMENT '文件下载地址',
    `size`         int          NOT NULL COMMENT '文件大小',
    `create_stamp` timestamp    NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上传时间戳(UTC时间)',
    `update_stamp` timestamp    NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间戳(UTC时间)',
    PRIMARY KEY (`id`),
    UNIQUE KEY `unique_uuid` (`uuid`),
    KEY `index_overlay_search` (`update_stamp` DESC, `type`, `name`, `url`, `size`, `uuid`) COMMENT '覆盖索引-查询',
    KEY `index_overlay_modify` (`uuid`, `name`) COMMENT '覆盖索引-删改'
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_0900_ai_ci;

服务层对 UTC 时间进行转换

def stamp_to_int(stamp) -> int:
    # 将时间对象转换为时间元组(time.struct_time 对象)。时间元组是一个包含了年、月、日、小时、分钟、秒等时间信息的对象
    timetuple = stamp.timetuple()
    # 将 TIMESTAMP 转换为时间戳
    float_stamp = time.mktime(timetuple)
    return int(float_stamp)

def switch_timezone(stamp):
    # 接收 UTC 时间
    utc_time = stamp
    # 获取当前系统时间
    now = datetime.now()
    # 获取当前系统时区
    local_timezone = now.astimezone().tzinfo
    local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(local_timezone)
    return local_time

def trans_time(stamp):
    """
    将 utc 时间转换成当前时区的时间戳,并返回时间戳整数值
    :param stamp:
    :return:
    """
    return stamp_to_int(switch_timezone(stamp))

UI 对时间戳进行转换

在这里插入图片描述

效果

在这里插入图片描述

注意,这里要对时间戳 * 1000,否则会如下图所示,回到 1970 年哦

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值