首页 > 其他分享 >golang处理时区

golang处理时区

时间:2022-11-14 08:35:01浏览次数:70  
标签:LoadLocation 处理 ZONEINFO golang go time Go 时区

很多Golang初学者都不知道怎么来处理时区问题.这篇文章将解释清楚一下两个问题:

  1. 怎么把带时区的时间保存到数据库?
  2. 在Go语言中怎么解析带时区的时间?

1. 数据库时区(Time Zone)原则

时间保存到数据库中要总是使用一个统一的时区,理想的状态是保存UTC时区.更绝需求来转换成需要的时区.

我们拿MySQL保存时间为例子,其他类型数据库也使用. 在MySQL官方文档中,有两种程序时间的类型:

  • DATETIME: DATETIME 长度8个字节,保存格式为 YYYYMMDDHHMMSS(年月日时分秒)的整数, 所以它与时区无关,存入的是什么值就是什么值,不会根据当前时区进行转换,支持范围 1000-01-01 00:00:00 到 9999-12-31 23:59:59
  • TIMESTAMP: TIMESTAMP 长度4字节,存入的是自1970-01-01午夜(格林尼治标准时间)以来的秒数, 它和unix时间戳相同.所以它与时区有关,查询时转为相应的时区时间.

现在最重要的事情是怎么来做时区的转换.

2. Go语言时间时区的转换

下面的代码是展示我们如何在Go语言中做时区的转换. 首先让我们来定义地区和时区的的字典. 时区列表IANA时区标识可以从这里得到Time Zones,

package main

import (
	"fmt"
	"errors"
	"time"
)

type Country string

const (
	Germany Country = "Germany"
	UnitedStates Country  = "United States"
	China Country = "China"

)

// timeZoneID 是国家=>IANA 标准时区标识符 的键值对字典
var timeZoneID = map[Country]string{
	Germany:      "Europe/Berlin",
	UnitedStates: "America/Los_Angeles",
	China:   "Asia/Shanghai",
}

//获取 IANA 时区标识符
func (c Country) TimeZoneID() (string, error) {
	if id, ok := timeZoneID[c]; ok {
		return id, nil
	}
	return "", errors.New("timezone id not found for country")
}

// 获取tz时区标识符的格式化时间字符
func TimeIn(t time.Time, tz, format string) string {
	
	// https:/golang.org/pkg/time/#LoadLocation loads location on
	// 加载时区
	loc, err := time.LoadLocation(tz)
	if err != nil {
		//handle error
	}
	// 获取指定时区的格式化时间字符串
	return t.In(loc).Format(format)
}

func main() {
	// 获取美国的时区结构体
	tz, err := UnitedStates.TimeZoneID()
	if err != nil {
		//handle error
	}
    //格式化成美国的时区
	usTime := TimeIn(time.Now(), tz, time.RFC3339)

	fmt.Printf("Time in %s: %s",
		UnitedStates,
		usTime,
	)
}

3. Go语言time.LoadLocation可能的坑

正如标准库文档中所说的:

The time zone database needed by LoadLocation may not be present on all systems, especially non-Unix systems. LoadLocation looks in the directory or uncompressed zip file named by the ZONEINFO environment variable, if any, then looks in known installation locations on Unix systems, and finally looks in $GOROOT/lib/time/zoneinfo.zip.

LoadLocation所需的时区数据库可能并不存在于所有系统上,尤其是非unix系统. 如果有的话,LoadLocation查找由ZONEINFO环境变量命名的目录或未压缩的 ZONEINFO 环境变量命名的zip文件, 然后查找Unix系统上已知的安装位置,最后查找 $GOROOT/lib/time/ ZONEINFO .zip.

4. Docker Go语言使用时区

默认的情况下时区信息文件时在Go安装的时候已经存在. 但是万一您部署和编译docker使用的时 multi-stage-docker Alpine 镜像.您可以手动的使用一下命令来添加时区的数据.

RUN apk add tzdata

这将把时区信息添加到 alpine 镜像的 /usr/share/timezone. 但是也不要忘记设置环境变量 ZONEINFO 的值为 /usr/share/timezone

ZONEINFO=/usr/share/timezone

这里有一个参考的示例 Dockerfile

FROM golang:1.12-alpine as build_base
RUN apk add --update bash make git
WORKDIR /go/src/github.com/your_repo/your_app/
ENv GO111MODULE on
COPY go.mod .
COPY go.sum .
RUN go mod download

FROM build_bash AS server_builder
COPY . ./
RUN GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /go/bin/your_app

FROM alpine
RUN apk add tzdata

# 自定义运行阶段的命令

标签:LoadLocation,处理,ZONEINFO,golang,go,time,Go,时区
From: https://www.cnblogs.com/cheyunhua/p/16887914.html

相关文章

  • 冷知识:预处理字符串操作符
    以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「englyf」https://mp.weixin.qq.com/s/Xr2pFCJ4j0DZYo2PO6-KQg当年学习C语言的第一门课就提到过标记(Tok......
  • mybatis中特殊符号(大于号、小于号)的处理
    1、预定义字符<<=相当于=><小于号><=相当于=>>大于号案例:<selectid="a"parameterType="java.lang.String"resultType="com.gao.entity.MyDe......
  • 结果集处理
    GET_search{"query":{"match_all":{}}}#模拟请求GET/#测试分词器POST/_analyze{"text":"黑马程序员学习java太棒了","analyzer":"ik_max_word"}#......
  • 虚拟串口无法删除的处理方法
    问题表现:虚拟串口无法删除1、虚拟串口无法删除2、设备管理器里出现虚拟设备,禁用后任然无法消除 处理方法:1、拔掉硬件的串口设备2、打开注册表:计算机\HKEY_LOCAL_MAC......
  • Python 处理Protobuf协议
    安装protobuf使用HomeBrew安装Protobuf:brew install protobuf查看是否安装成功protoc --version进入文件路径命令行执行protoc--python_out=././HT_mo......
  • defer+recover机制处理错误
    defer+recover机制处理错误Go中追求代码优雅,引入机制:defer+recover机制处理错误内置函数recover:packagemainimport"fmt"funcmain(){ test() fmt.Println("上......
  • golang fmt && lint
    如何轻松使用格式化和静态检查工具makefmtmakelint 1、go.mod同级目录创建文件Makefilefmt:command-vgofumpt||(WORK=$(shellpwd)&&cd/tmp&&......
  • golang内存对齐的重要性
     结构体中字段类型的改变直接造成内存对齐结果的改变,是的占用内存空间也不一样packagemainimport( "fmt" "unsafe")funcmain(){ varxxstruct{ aboo......
  • Springboot中-全局异常处理类用法示例
    使用springboot搭建web项目的时候,一般都会添加一个全局异常类,用来统一处理各种自定义异常信息,和其他非自定义的异常信息,以便于统一返回错误信息。下面就是简单的示例......
  • 【广义S变换】一维广义S变换对非平稳信号处理的matlab仿真
    1.软件版本matlab2013b2.本算法理论知识参考文献:《时频分布与地震信号谱分析研究》《非平稳信号广义S不变换及其在SAR图像分析中的应用研究》《广义S变换及其时频滤......