我的编程空间,编程开发者的网络收藏夹
学习永远不晚

我应该如何在 Postgres 中存储 Go 的 time.Location ?

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

我应该如何在 Postgres 中存储 Go 的 time.Location ?

你在学习Golang相关的知识吗?本文《我应该如何在 Postgres 中存储 Go 的 time.Location ?》,主要介绍的内容就涉及到,如果你想提升自己的开发能力,就不要错过这篇文章,大家要知道编程理论基础和实战操作都是不可或缺的哦!

问题内容

在 postgres 中,我存储用户提供给我的数据:

column   |           type           | collation | nullable | default
------------+--------------------------+-----------+----------+---------
 id         | uuid                     |           | not null |
 value      | numeric                  |           |          |
 date       | timestamp with time zone |           |          |

现在我需要维护生成数据的原始时区。带有 timezone 的 timestamp 已标准化为数据库的时区,并且原始时区丢失,因此我必须手动将 date 从标准化时区恢复回来,然后再将其返回给用户。

大多数解决方案建议在表中添加额外的列,并将原始时区信息与时间戳一起存储:

Column   |           Type           | Collation | Nullable | Default
------------+--------------------------+-----------+----------+---------
 id         | uuid                     |           | not null |
 value      | numeric                  |           |          |
 date       | timestamp with time zone |           |          |
 tz         | text                     |           |          |

鉴于我使用的是 go,我应该从 time.time 中提取哪些信息来存储在 tz 中以获得最精确和无缝的恢复?

date.location().string() 似乎不正确,因为它可能返回相对值 local

我应该如何将 tz 中的信息恢复到 time.time 中?

time.loadlocation(tz) 的结果是否足够好?


解决方案


保存后,我将使用 Time.Zone() 获取区域名称和偏移量:

func (t time) zone() (name string, offset int)

那么从数据库查询这样的时间戳时,可以使用time.FixedZone()构造一个time.Location

func fixedzone(name string, offset int) *location

并使用 Time.In() 切换到此位置。

请注意!这将为您恢复一个“看似”在同一时区的时间戳,但如果您需要对其进行操作(例如向其添加天数),则结果可能不一样。原因是因为 time.fixedzone() 返回一个具有固定偏移量的时区,例如,它不知道有关 daylight savings 的任何信息,而您保存的原始时间戳可能有一个 time.location ,它确实知道这些事情。

以下是此类偏差的示例。 3 月有夏令时,因此我们将使用指向 3 月 1 日的时间戳,并为其添加 1 个月,这会导致时间戳位于夏令时之后。

cet, err := time.loadlocation("cet")
if err != nil {
    panic(err)
}

t11 := time.date(2019, time.march, 1, 12, 0, 0, 0, cet)
t12 := t11.adddate(0, 1, 0)
fmt.println(t11, t12)

name, offset := t11.zone()
cet2 := time.fixedzone(name, offset)
t21 := t11.utc().in(cet2)
t22 := t21.adddate(0, 1, 0)
fmt.println(t21, t22)

now := time.date(2019, time.april, 2, 0, 0, 0, 0, time.utc)
fmt.println("time since t11:", now.sub(t11))
fmt.println("time since t21:", now.sub(t21))
fmt.println("time since t12:", now.sub(t12))
fmt.println("time since t22:", now.sub(t22))

这将输出(在 Go Playground 上尝试):

2019-03-01 12:00:00 +0100 cet 2019-04-01 12:00:00 +0200 cest
2019-03-01 12:00:00 +0100 cet 2019-04-01 12:00:00 +0100 cet
time since t11: 757h0m0s
time since t21: 757h0m0s
time since t12: 14h0m0s
time since t22: 13h0m0s

如您所见,添加 1 个月后的输出时间是相同的,但区域偏移量不同,因此它们在时间上指定了不同的时刻(这可以通过显示与任意时间的时间差来证明) )。原始时间戳有 2 小时偏移,因为它知道我们跳过的 1 个月内发生的夏令时,而“恢复”时间戳的区域不知道这一点,因此结果具有相同的 1 小时偏移。在添加后的时间戳中,甚至区域名称在现实生活中也发生了变化:从 cetcest,并且恢复的时间戳的区域也不知道这一点。

更浪费,并且仍然容易出现错误,但仍然有效的解决方案是将原始时间戳以 iso 8601 格式存储,例如 2019-05-2t17:24:37+01:00 在单独的列 datetext 中:

Column   |           Type           | Collation | Nullable | Default
------------+--------------------------+-----------+----------+---------
 id         | uuid                     |           | not null |
 value      | numeric                  |           |          |
 date       | timestamp with time zone |           |          |
 datetext   | text                     |           |          |

然后使用 date 查询本机时间戳列的强度,并返回给用户 datetext,这是最初发送的确切值。

今天关于《我应该如何在 Postgres 中存储 Go 的 time.Location ?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在编程网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

我应该如何在 Postgres 中存储 Go 的 time.Location ?

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

我应该如何在 Postgres 中存储 Go 的 time.Location ?

你在学习Golang相关的知识吗?本文《我应该如何在 Postgres 中存储 Go 的 time.Location ?》,主要介绍的内容就涉及到,如果你想提升自己的开发能力,就不要错过这篇文章,大家要知道编程理论基础和实战操作都是不可或缺
我应该如何在 Postgres 中存储 Go 的 time.Location ?
2024-04-04

详解如何使用beegoorm在postgres中存储图片

这篇文章主要为大家介绍了如何使用beegoorm在postgres中存储图片详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-17

我如何解组 JSON 数据并将其存储在 Go 中的结构中

php小编草莓分享一种解组JSON数据并将其存储在Go语言结构中的方法。JSON是一种常用的数据交换格式,Go语言提供了方便的解析和处理JSON数据的工具包。通过使用Go语言内置的"json"包,我们可以轻松地将JSON数据解组成相应的结构
我如何解组 JSON 数据并将其存储在 Go 中的结构中
2024-02-11

我应该如何在golang中使用类型mapinterface {}

问题内容我正在尝试从 api 检索数据。当我从api获取数据时:result, _ := s.getcases() // get cases via apifmt.println(reflect.typeof(result.recor
我应该如何在golang中使用类型mapinterface {}
2024-02-06

我们如何在用户定义的变量中存储值?

我们可以在语句中将一个值存储在用户定义的变量中,然后在其他语句中引用它。以下是存储用户定义变量值的方法:使用SET语句我们可以通过发出SET语句来存储用户定义变量,如下所示:语法SET @var_name = expr[, @var_nam
2023-10-22

我们如何在 MySQL 存储过程中处理结果集?

我们可以使用游标来处理存储过程中的结果集。基本上,游标允许我们迭代查询返回的一组行并相应地处理每一行。为了演示 CURSOR 在 MySQL 存储过程中的使用,我们正在创建以下存储过程,该过程基于名为“student_info”的表的值,如
2023-10-22

我们如何在 MySQL 存储过程中执行 COMMIT 事务?

众所周知,START 事务将启动事务,而 COMMIT 用于在启动事务后进行任何更改。在下面的示例中,我们使用 COMMIT 和 START 事务创建了一个存储过程,它将插入一条新记录并在具有以下数据的表“employee.tbl”中提交更
2023-10-22

我们如何在MySQL表的列中存储的日期中添加天/秒?

两个函数可用于此目的,并且在这两个函数中,我们需要提供列名作为参数以及 INTERVAL 关键字。函数如下 -DATE_ADD() 函数该函数的语法为 DATE_ADD(date, INTERVAL 表达式单元)。可以通过使用表“colle
2023-10-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录