Skip to content

Commit 2a0d34e

Browse files
committed
fix: fix os.date("!*t", os.time()) will not get UTC date time issue
1 parent d212719 commit 2a0d34e

File tree

2 files changed

+147
-2
lines changed

2 files changed

+147
-2
lines changed

baselib_test.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package lua
2+
3+
import (
4+
"strconv"
5+
"testing"
6+
"time"
7+
)
8+
9+
func TestOsDateFormatUTCWithTwoParam(t *testing.T) {
10+
t.Setenv("TZ", "Asia/Tokyo")
11+
ls := NewState()
12+
13+
g := ls.GetGlobal("os")
14+
fn := ls.GetField(g, "date")
15+
16+
int64ptr := func(i int64) *int64 {
17+
return &i
18+
}
19+
cases := []struct {
20+
Name string
21+
Local time.Time
22+
Now time.Time
23+
Format string
24+
Timestamp *int64
25+
}{
26+
{
27+
"UTCWithTwoParam",
28+
time.Now(),
29+
time.Now().UTC(),
30+
"!*t",
31+
int64ptr(time.Now().UTC().Unix()),
32+
},
33+
{
34+
"LocalWithTwoParam",
35+
time.Now(),
36+
time.Now(),
37+
"*t",
38+
int64ptr(time.Now().Unix()),
39+
},
40+
{
41+
"UTCWithOnlyFormatParam",
42+
time.Now(),
43+
time.Now().UTC(),
44+
"!*t",
45+
nil,
46+
},
47+
{
48+
"LocalWithOnlyFormatParam",
49+
time.Now(),
50+
time.Now(),
51+
"*t",
52+
nil,
53+
},
54+
}
55+
56+
for _, c := range cases {
57+
t.Run(c.Name, func(t *testing.T) {
58+
args := make([]LValue, 0)
59+
args = append(args, LString(c.Format))
60+
if c.Timestamp != nil {
61+
args = append(args, LNumber(*c.Timestamp))
62+
}
63+
err := ls.CallByParam(P{
64+
Fn: fn,
65+
NRet: 1,
66+
Protect: true,
67+
}, args...)
68+
if err != nil {
69+
t.Fatal(err)
70+
}
71+
72+
result := ls.ToTable(-1)
73+
74+
resultMap := make(map[string]string)
75+
result.ForEach(func(key LValue, value LValue) {
76+
resultMap[key.String()] = value.String()
77+
assertOsDateFields(t, key, value, c.Now)
78+
})
79+
t.Logf("%v resultMap=%+v\nnow=%+v\nLocal=%+v\nUTC=%v", c.Name, resultMap, c.Now, c.Local, c.Now.UTC())
80+
})
81+
}
82+
}
83+
84+
func TestOsDateFormatLocalWithTwoParam(t *testing.T) {
85+
t.Setenv("TZ", "Asia/Tokyo")
86+
ls := NewState()
87+
88+
g := ls.GetGlobal("os")
89+
fn := ls.GetField(g, "date")
90+
91+
nowLocal := time.Now()
92+
nowUTC := nowLocal.UTC()
93+
94+
err := ls.CallByParam(P{
95+
Fn: fn,
96+
NRet: 1,
97+
Protect: true,
98+
}, LString("*t"), LNumber(nowLocal.Unix()))
99+
if err != nil {
100+
t.Fatal(err)
101+
}
102+
103+
result := ls.ToTable(-1)
104+
105+
resultMap := make(map[string]string)
106+
result.ForEach(func(key LValue, value LValue) {
107+
t.Logf("key=%v, value=%v", key, value)
108+
resultMap[key.String()] = value.String()
109+
assertOsDateFields(t, key, value, nowLocal)
110+
})
111+
t.Logf("resultMap=%+v, nowLocal=%+v, nowUTC=%v", resultMap, nowLocal, nowUTC)
112+
}
113+
114+
func assertOsDateFields(t *testing.T, key LValue, value LValue, expect time.Time) {
115+
switch key.String() {
116+
case "year":
117+
if value.String() != strconv.Itoa(expect.Year()) {
118+
t.Errorf("year=%v, expect.Year=%v", value.String(), expect.Year())
119+
}
120+
case "month":
121+
if value.String() != strconv.Itoa(int(expect.Month())) {
122+
t.Errorf("month=%v, expect.Month=%v", value.String(), expect.Month())
123+
}
124+
case "day":
125+
if value.String() != strconv.Itoa(expect.Day()) {
126+
t.Errorf("day=%v, expect.Day=%v", value.String(), expect.Day())
127+
}
128+
case "hour":
129+
if value.String() != strconv.Itoa(expect.Hour()) {
130+
t.Errorf("hour=%v, expect.Hour=%v", value.String(), expect.Hour())
131+
}
132+
case "min":
133+
if value.String() != strconv.Itoa(expect.Minute()) {
134+
t.Errorf("min=%v, expect.Minute=%v", value.String(), expect.Minute())
135+
}
136+
case "sec":
137+
if value.String() != strconv.Itoa(expect.Second()) {
138+
t.Errorf("sec=%v, expect.Second=%v", value.String(), expect.Second())
139+
}
140+
}
141+
}

oslib.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func getIntField(L *LState, tb *LTable, key string, v int) int {
2323
slv := string(lv)
2424
slv = strings.TrimLeft(slv, " ")
2525
if strings.HasPrefix(slv, "0") && !strings.HasPrefix(slv, "0x") && !strings.HasPrefix(slv, "0X") {
26-
//Standard lua interpreter only support decimal and hexadecimal
26+
// Standard lua interpreter only support decimal and hexadecimal
2727
slv = strings.TrimLeft(slv, "0")
2828
if slv == "" {
2929
return 0
@@ -106,16 +106,20 @@ func osExit(L *LState) int {
106106

107107
func osDate(L *LState) int {
108108
t := time.Now()
109+
isUTC := false
109110
cfmt := "%c"
110111
if L.GetTop() >= 1 {
111112
cfmt = L.CheckString(1)
112113
if strings.HasPrefix(cfmt, "!") {
113-
t = time.Now().UTC()
114114
cfmt = strings.TrimLeft(cfmt, "!")
115+
isUTC = true
115116
}
116117
if L.GetTop() >= 2 {
117118
t = time.Unix(L.CheckInt64(2), 0)
118119
}
120+
if isUTC {
121+
t = t.UTC()
122+
}
119123
if strings.HasPrefix(cfmt, "*t") {
120124
ret := L.NewTable()
121125
ret.RawSetString("year", LNumber(t.Year()))

0 commit comments

Comments
 (0)