- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章golang的时区和神奇的time.Parse的使用方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
。
。
先写一段测试代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
const TIME_LAYOUT = "2006-01-02 15:04:05"
func parseWithLocation(name string, timeStr string) (time.Time, error) {
locationName := name
if l, err := time.LoadLocation(locationName); err != nil {
println(err.Error())
return time.Time{}, err
} else {
lt, _ := time.ParseInLocation(TIME_LAYOUT, timeStr, l)
fmt.Println(locationName, lt)
return lt, nil
}
}
func testTime() {
fmt.Println("0. now: ", time.Now())
str := "2018-09-10 00:00:00"
fmt.Println("1. str: ", str)
t, _ := time.Parse(TIME_LAYOUT, str)
fmt.Println("2. Parse time: ", t)
tStr := t.Format(TIME_LAYOUT)
fmt.Println("3. Format time str: ", tStr)
name, offset := t.Zone()
name2, offset2 := t.Local().Zone()
fmt.Printf("4. Zone name: %v, Zone offset: %v\n", name, offset)
fmt.Printf("5. Local Zone name: %v, Local Zone offset: %v\n", name2, offset2)
tLocal := t.Local()
tUTC := t.UTC()
fmt.Printf("6. t: %v, Local: %v, UTC: %v\n", t, tLocal, tUTC)
fmt.Printf("7. t: %v, Local: %v, UTC: %v\n", t.Format(TIME_LAYOUT), tLocal.Format(TIME_LAYOUT), tUTC.Format(TIME_LAYOUT))
fmt.Printf("8. Local.Unix: %v, UTC.Unix: %v\n", tLocal.Unix(), tUTC.Unix())
str2 := "1969-12-31 23:59:59"
t2, _ := time.Parse(TIME_LAYOUT, str2)
fmt.Printf("9. str2:%v,time: %v, Unix: %v\n", str2, t2, t2.Unix())
fmt.Printf("10. %v, %v\n", tLocal.Format(time.ANSIC), tUTC.Format(time.ANSIC))
fmt.Printf("11. %v, %v\n", tLocal.Format(time.RFC822), tUTC.Format(time.RFC822))
fmt.Printf("12. %v, %v\n", tLocal.Format(time.RFC822Z), tUTC.Format(time.RFC822Z))
//指定时区
parseWithLocation("America/Cordoba", str)
parseWithLocation("Asia/Shanghai", str)
parseWithLocation("Asia/Beijing", str)
}
testTime()
|
输出:
0. now: 2018-09-19 19:06:07.3642781 +0800 CST m=+0.005995601 1. str: 2018-09-10 00:00:00 2. Parse time: 2018-09-10 00:00:00 +0000 UTC 3. Format time str: 2018-09-10 00:00:00 4. Zone name: UTC, Zone offset: 0 5. Local Zone name: CST, Local Zone offset: 28800 6. t: 2018-09-10 00:00:00 +0000 UTC, Local: 2018-09-10 08:00:00 +0800 CST, UTC: 2018-09-10 00:00:00 +0000 UTC 7. t: 2018-09-10 00:00:00, Local: 2018-09-10 08:00:00, UTC: 2018-09-10 00:00:00 8. Local.Unix: 1536537600, UTC.Unix: 1536537600 9. str2:1969-12-31 23:59:59,time: 1969-12-31 23:59:59 +0000 UTC, Unix: -1 10. Mon Sep 10 08:00:00 2018, Mon Sep 10 00:00:00 2018 11. 10 Sep 18 08:00 CST, 10 Sep 18 00:00 UTC 12. 10 Sep 18 08:00 +0800, 10 Sep 18 00:00 +0000 America/Cordoba 2018-09-10 00:00:00 -0300 -03 Asia/Shanghai 2018-09-10 00:00:00 +0800 CST cannot find Asia/Beijing in zip file C:\Go\/lib/time/zoneinfo.zip 。
从以上代码的测试结果可以得出几点:
。
。
一开始使用time.Parse时很不习惯,因为非常奇怪的layout参数。 除了golang自带定义的layout:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
const (
ANSIC = "Mon Jan _2 15:04:05 2006"
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
RFC822 = "02 Jan 06 15:04 MST"
RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen = "3:04PM"
// Handy time stamps.
Stamp = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
StampMicro = "Jan _2 15:04:05.000000"
StampNano = "Jan _2 15:04:05.000000000"
)
|
还可以自定义layout,比如:
"2006-01-02 15:04:05" 。
网上基本上都在传说这个日子是golang项目开始创建的时间,为了纪念生日才这样设计,其实这真是无稽之谈瞎扯淡。 网上文章没有找到说的比较清楚的,幸好有源码,打开time.Parse的源码看了一下,发现这个设计很好很科学。 解析layout的主要代码在nextStdChunk方法中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// nextStdChunk finds the first occurrence of a std string in
// layout and returns the text before, the std string, and the text after.
func nextStdChunk(layout string) (prefix string, std int, suffix string) {
for i := 0; i < len(layout); i++ {
switch c := int(layout[i]); c {
case 'J': // January, Jan
if len(layout) >= i+3 && layout[i:i+3] == "Jan" {
if len(layout) >= i+7 && layout[i:i+7] == "January" {
return layout[0:i], stdLongMonth, layout[i+7:]
}
if !startsWithLowerCase(layout[i+3:]) {
return layout[0:i], stdMonth, layout[i+3:]
}
}
case 'M': // Monday, Mon, MST
if len(layout) >= i+3 {
if layout[i:i+3] == "Mon" {
if len(layout) >= i+6 && layout[i:i+6] == "Monday" {
return layout[0:i], stdLongWeekDay, layout[i+6:]
}
if !startsWithLowerCase(layout[i+3:]) {
return layout[0:i], stdWeekDay, layout[i+3:]
}
}
if layout[i:i+3] == "MST" {
return layout[0:i], stdTZ, layout[i+3:]
}
}
case '0': // 01, 02, 03, 04, 05, 06
if len(layout) >= i+2 && '1' <= layout[i+1] && layout[i+1] <= '6' {
return layout[0:i], std0x[layout[i+1]-'1'], layout[i+2:]
}
case '1': // 15, 1
if len(layout) >= i+2 && layout[i+1] == '5' {
return layout[0:i], stdHour, layout[i+2:]
}
return layout[0:i], stdNumMonth, layout[i+1:]
case '2': // 2006, 2
if len(layout) >= i+4 && layout[i:i+4] == "2006" {
return layout[0:i], stdLongYear, layout[i+4:]
}
return layout[0:i], stdDay, layout[i+1:]
case '_': // _2, _2006
if len(layout) >= i+2 && layout[i+1] == '2' {
//_2006 is really a literal _, followed by stdLongYear
if len(layout) >= i+5 && layout[i+1:i+5] == "2006" {
return layout[0 : i+1], stdLongYear, layout[i+5:]
}
return layout[0:i], stdUnderDay, layout[i+2:]
}
case '3':
return layout[0:i], stdHour12, layout[i+1:]
case '4':
return layout[0:i], stdMinute, layout[i+1:]
case '5':
return layout[0:i], stdSecond, layout[i+1:]
case 'P': // PM
if len(layout) >= i+2 && layout[i+1] == 'M' {
return layout[0:i], stdPM, layout[i+2:]
}
case 'p': // pm
if len(layout) >= i+2 && layout[i+1] == 'm' {
return layout[0:i], stdpm, layout[i+2:]
}
case '-': // -070000, -07:00:00, -0700, -07:00, -07
if len(layout) >= i+7 && layout[i:i+7] == "-070000" {
return layout[0:i], stdNumSecondsTz, layout[i+7:]
}
if len(layout) >= i+9 && layout[i:i+9] == "-07:00:00" {
return layout[0:i], stdNumColonSecondsTZ, layout[i+9:]
}
if len(layout) >= i+5 && layout[i:i+5] == "-0700" {
return layout[0:i], stdNumTZ, layout[i+5:]
}
if len(layout) >= i+6 && layout[i:i+6] == "-07:00" {
return layout[0:i], stdNumColonTZ, layout[i+6:]
}
if len(layout) >= i+3 && layout[i:i+3] == "-07" {
return layout[0:i], stdNumShortTZ, layout[i+3:]
}
case 'Z': // Z070000, Z07:00:00, Z0700, Z07:00,
if len(layout) >= i+7 && layout[i:i+7] == "Z070000" {
return layout[0:i], stdISO8601SecondsTZ, layout[i+7:]
}
if len(layout) >= i+9 && layout[i:i+9] == "Z07:00:00" {
return layout[0:i], stdISO8601ColonSecondsTZ, layout[i+9:]
}
if len(layout) >= i+5 && layout[i:i+5] == "Z0700" {
return layout[0:i], stdISO8601TZ, layout[i+5:]
}
if len(layout) >= i+6 && layout[i:i+6] == "Z07:00" {
return layout[0:i], stdISO8601ColonTZ, layout[i+6:]
}
if len(layout) >= i+3 && layout[i:i+3] == "Z07" {
return layout[0:i], stdISO8601ShortTZ, layout[i+3:]
}
case '.': // .000 or .999 - repeated digits for fractional seconds.
if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
ch := layout[i+1]
j := i + 1
for j < len(layout) && layout[j] == ch {
j++
}
// String of digits must end here - only fractional second is all digits.
if !isDigit(layout, j) {
std := stdFracSecond0
if layout[i+1] == '9' {
std = stdFracSecond9
}
std |= (j - (i + 1)) << stdArgShift
return layout[0:i], std, layout[j:]
}
}
}
}
return layout, 0, ""
}
|
可以发现layout的所有代表年月日时分秒甚至时区的值都是互斥不相等的.
比如年份:短年份06,长年份2006, 月份:01,Jan,January 日:02,2,_2 时:15,3,03 分:04, 4 秒:05, 5 。
因为都不相等所以通过遍历layout就可以switch case解析出每个区块的意义和在字符串中的位置,这样输入对应格式的时间字符串就可以顺利解析出来。 这样layout也可以自定义,而且顺序任意,只要符合下列每个区块定义的规则即可, 代码中的注释就是规则写法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
const (
_ = iota
stdLongMonth = iota + stdNeedDate // "January"
stdMonth // "Jan"
stdNumMonth // "1"
stdZeroMonth // "01"
stdLongWeekDay // "Monday"
stdWeekDay // "Mon"
stdDay // "2"
stdUnderDay // "_2"
stdZeroDay // "02"
stdHour = iota + stdNeedClock // "15"
stdHour12 // "3"
stdZeroHour12 // "03"
stdMinute // "4"
stdZeroMinute // "04"
stdSecond // "5"
stdZeroSecond // "05"
stdLongYear = iota + stdNeedDate // "2006"
stdYear // "06"
stdPM = iota + stdNeedClock // "PM"
stdpm // "pm"
stdTZ = iota // "MST"
stdISO8601TZ // "Z0700" // prints Z for UTC
stdISO8601SecondsTZ // "Z070000"
stdISO8601ShortTZ // "Z07"
stdISO8601ColonTZ // "Z07:00" // prints Z for UTC
stdISO8601ColonSecondsTZ // "Z07:00:00"
stdNumTZ // "-0700" // always numeric
stdNumSecondsTz // "-070000"
stdNumShortTZ // "-07" // always numeric
stdNumColonTZ // "-07:00" // always numeric
stdNumColonSecondsTZ // "-07:00:00"
stdFracSecond0 // ".0", ".00", ... , trailing zeros included
stdFracSecond9 // ".9", ".99", ..., trailing zeros omitted
stdNeedDate = 1 << 8 // need month, day, year
stdNeedClock = 2 << 8 // need hour, minute, second
stdArgShift = 16 // extra argument in high bits, above low stdArgShift
stdMask = 1<<stdArgShift - 1 // mask out argument
)
|
。
。
时区使用:MST 时区偏移使用-0700或者Z0700等等。 下面是一个使用时区的例子,Z0700比较特殊,当输入时间直接使用Z时就直接代表UTC时区.
1
2
3
4
5
6
7
8
9
10
11
12
|
func testTimeParse() {
t, _ := time.Parse("2006-01-02 15:04:05 -0700 MST", "2018-09-20 15:39:06 +0800 CST")
fmt.Println(t)
t, _ = time.Parse("2006-01-02 15:04:05 -0700 MST", "2018-09-20 15:39:06 +0000 CST")
fmt.Println(t)
t, _ = time.Parse("2006-01-02 15:04:05 Z0700 MST", "2018-09-20 15:39:06 +0800 CST")
fmt.Println(t)
t, _ = time.Parse("2006-01-02 15:04:05 Z0700 MST", "2018-09-20 15:39:06 Z GMT")
fmt.Println(t)
t, _ = time.Parse("2006-01-02 15:04:05 Z0700 MST", "2018-09-20 15:39:06 +0000 GMT")
fmt.Println(t)
}
|
输出: 2018-09-20 15:39:06 +0800 CST 2018-09-20 15:39:06 +0000 CST 2018-09-20 15:39:06 +0800 CST 2018-09-20 15:39:06 +0000 UTC 2018-09-20 15:39:06 +0000 GMT 。
还有疑问的可以看看go自带的测试例子:Go/src/time/example_test.go 。
到此这篇关于golang的时区和神奇的time.Parse的使用方法的文章就介绍到这了,更多相关golang的时区和time.Parse内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://www.jianshu.com/p/f809b06144f7 。
最后此篇关于golang的时区和神奇的time.Parse的使用方法的文章就讲到这里了,如果你想了解更多关于golang的时区和神奇的time.Parse的使用方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在我的 Rails (3.0) 应用程序中,我使用助手 time_zone_select() 来使用时区。它生成时区名称,如“(GMT+01:00) Paris”... 但这些名称与 MySQL 中的
我正在解析格式为的日期: SimpleDateFormat formatter = new SimpleDateFormat("EE MMM dd HH:mm:ss Z yyyy"); 当我这样做的时
我在 Android 上使用 ACTION_TIMEZONE_CHANGED Intent 过滤器来响应时区更改。 我注意到 Jodas 当前时区此时没有更新,使用:DateTimeZone.getD
我有一个旧版 Windows 应用程序,它从数据库读取数据。其中一列是“TimeZoneInfoId”。在传统世界中,它是由另一个 Windows 应用程序编写的,因此它存储 Windows 字符串:
我是数据库开发新手,目前从事 MySQL 工作。我有一列包含美国的所有时区。我希望能够获取每行中每个时区的当前时间(只有时间,没有日期)。 时区数据如下:+05:00、-03:00 等等 这就是我尝试
我正在尝试了解 session 时区在 PostgreSQL 中的工作原理。 当我将 session 时区设置为“01:00”时,返回日期为“-01:00”。符号总是颠倒的,我不理解这种行为。 这怎么
我写入我的 mongoDB 数据库,例如开始日期,开始日期始终是一周中的星期一(我使用并且我在欧洲中部时区)。 "startDate" : ISODate("2014-12-28T23:00:00Z"
是否有详尽的 MySQL 时区列表? 似乎 MySQL 设置中 time_zone 的有效值取决于主机操作系统,但我一直无法找到可能值的列表。 我需要时间显示卡尔加里本地时间。 最佳答案 默认情况下,
我已经在 config/app.php 中配置了时区至 Europe/Lisbon . 如果我做 return date_default_timezone_get(); , 返回 Europe/Lis
我在整个脚本中广泛使用 unix 时间,通常我将时区设置如下: date_default_timezone_set('Europe/London'); 这一直工作正常,直到上周末时钟回退一个小时,我怀
我有一个字符串,2013-10-07T23:59:51.205-07:00,想将其转换为 Java 日期对象。我收到解析错误。 date = new SimpleDateFormat("yyyy-MM
如何更改日志文件名中的 log4j 时区? 我的 log4j.xml 文件:
在JAVA中,如何确定所有日期都作为GMT日期返回? 例如,即使我尝试使用GMT语言环境强制使用DateFormat,它也会应用某种逻辑来检索BST日期。 public static void mai
好吧,这是我遇到过的最奇怪的错误之一! 首先:我不是 Python 程序员,该脚本是由 friend 编写的(我认为他的大部分内容来自示例)。 该脚本的用途:将日历信息(CET 时间)从 XML 文件
我们有一个网站,目前在某个时间(由用户选择)运行拍卖,这一切都工作正常,因为当服务器到达该时间时,拍卖就会开始。然后我们必须添加时区,具体取决于用户居住的地方。然后,根据所选的下拉菜单,这将增加或减少
我陷入了这个逻辑。我正在开发一个消息调度项目,我的客户来自不同的国家。让我们考虑一下亚洲(不遵守夏令时)和美国/纽约(遵守夏令时)。 现在,我正在编写以下查询来获取距当前时间 10 分钟间隔内的时间表
我尝试返回特定时区的值,但我遇到了一些奇怪的响应行为: SELECT created_at AT TIME ZONE 'US/Pacific' - created_at, NOW() A
我正在尝试将不带时区值(例如“31.05.2015”)的字符串转换为 NSDate。 我的 DateFormatter 有什么问题?它返回日期 2015-05-31 22:00:00 +0000当我尝
我已经成功地将我的本地 tzinfo 导入到 mysql 中,我几乎已经了解了关于如何存储和使用这些数据的所有细节,除了一个字段。有一个名为 Transition_type_id 的数字字段(在表 t
为什么以下行返回的 TimeZone 显示不正确的时间: TimeZone.getTimeZone("America/Ottawa") 现在显示晚上 10:26 [亚特兰大时间现在是 6:26,Ott
我是一名优秀的程序员,十分优秀!