convert - String2Time accept HH:mm:ss format #2074

Merged
lunny merged 2 commits from arturwwl/xorm:time-fix into master 2023-07-23 02:34:16 +00:00
2 changed files with 22 additions and 7 deletions

View File

@ -15,6 +15,7 @@ import (
)
// String2Time converts a string to time with original location
// be aware for time strings (HH:mm:ss) returns zero year (LMT) for converted location
func String2Time(s string, originalLocation *time.Location, convertedLocation *time.Location) (*time.Time, error) {
if len(s) == 19 {
if s == utils.ZeroTime0 || s == utils.ZeroTime1 {
@ -32,6 +33,7 @@ func String2Time(s string, originalLocation *time.Location, convertedLocation *t
return nil, err
}
dt = dt.In(convertedLocation)
dt.IsZero()
return &dt, nil
} else if len(s) == 25 && s[10] == 'T' && s[19] == '+' && s[22] == ':' {
dt, err := time.Parse(time.RFC3339, s)
@ -48,7 +50,7 @@ func String2Time(s string, originalLocation *time.Location, convertedLocation *t
dt = dt.In(convertedLocation)
return &dt, nil
} else if len(s) >= 21 && s[19] == '.' {
var layout = "2006-01-02 15:04:05." + strings.Repeat("0", len(s)-20)
layout := "2006-01-02 15:04:05." + strings.Repeat("0", len(s)-20)
dt, err := time.ParseInLocation(layout, s, originalLocation)
if err != nil {
Outdated
Review

Why not just use convertedLocation here?

Why not just use `convertedLocation` here?

It depends on how it should work.
Does DB time should be always in sync with local time?
For example in location Europe/Warsaw time depends on date Wiki.
Should we expect that something stored in DB (if our DB has UTC time) at 8AM should be in Poland(UTC +1/UTC +2) 9AM/10AM depends on current date?
Also when we consider there is posibility that another go program (on other server) acces to this same DB from other location, I think it is clear it should correctly convert that time to local - example in Asia/Shanghai this should be shown as 4PM.

It depends on how it should work. Does DB time should be always in sync with local time? For example in location `Europe/Warsaw` time depends on date [Wiki](https://en.wikipedia.org/wiki/Time_in_Poland). Should we expect that something stored in DB (if our DB has `UTC` time) at `8AM` should be in Poland(`UTC +1/UTC +2`) `9AM/10AM` depends on current date? Also when we consider there is posibility that another go program (on other server) acces to this same DB from other location, I think it is clear it should correctly convert that time to local - example in `Asia/Shanghai` this should be shown as `4PM`.
return nil, err
@ -65,6 +67,18 @@ func String2Time(s string, originalLocation *time.Location, convertedLocation *t
}
dt = dt.In(convertedLocation)
return &dt, nil
} else if len(s) == 8 && s[2] == ':' && s[5] == ':' {
currentDate := time.Now()
dt, err := time.ParseInLocation("15:04:05", s, originalLocation)
if err != nil {
return nil, err
}
// add current date for correct time locations
dt = dt.AddDate(currentDate.Year(), int(currentDate.Month()), currentDate.Day())
dt = dt.In(convertedLocation)
// back to zero year
dt = dt.AddDate(-currentDate.Year(), int(-currentDate.Month()), -currentDate.Day())
return &dt, nil
} else {
i, err := strconv.ParseInt(s, 10, 64)
if err == nil {

View File

@ -15,7 +15,7 @@ func TestString2Time(t *testing.T) {
expectedLoc, err := time.LoadLocation("Asia/Shanghai")
assert.NoError(t, err)
var kases = map[string]time.Time{
cases := map[string]time.Time{
"2021-08-10": time.Date(2021, 8, 10, 8, 0, 0, 0, expectedLoc),
"2021-07-11 10:44:00": time.Date(2021, 7, 11, 18, 44, 0, 0, expectedLoc),
"2021-07-11 10:44:00.999": time.Date(2021, 7, 11, 18, 44, 0, 999000000, expectedLoc),
@ -25,12 +25,13 @@ func TestString2Time(t *testing.T) {
"2021-06-06T22:58:20.999+08:00": time.Date(2021, 6, 6, 22, 58, 20, 999000000, expectedLoc),
"2021-06-06T22:58:20.999999+08:00": time.Date(2021, 6, 6, 22, 58, 20, 999999000, expectedLoc),
"2021-06-06T22:58:20.999999999+08:00": time.Date(2021, 6, 6, 22, 58, 20, 999999999, expectedLoc),
"2021-08-10T10:33:04Z": time.Date(2021, 8, 10, 18, 33, 04, 0, expectedLoc),
"2021-08-10T10:33:04.999Z": time.Date(2021, 8, 10, 18, 33, 04, 999000000, expectedLoc),
"2021-08-10T10:33:04.999999Z": time.Date(2021, 8, 10, 18, 33, 04, 999999000, expectedLoc),
"2021-08-10T10:33:04.999999999Z": time.Date(2021, 8, 10, 18, 33, 04, 999999999, expectedLoc),
"2021-08-10T10:33:04Z": time.Date(2021, 8, 10, 18, 33, 0o4, 0, expectedLoc),
"2021-08-10T10:33:04.999Z": time.Date(2021, 8, 10, 18, 33, 0o4, 999000000, expectedLoc),
"2021-08-10T10:33:04.999999Z": time.Date(2021, 8, 10, 18, 33, 0o4, 999999000, expectedLoc),
"2021-08-10T10:33:04.999999999Z": time.Date(2021, 8, 10, 18, 33, 0o4, 999999999, expectedLoc),
"10:22:33": time.Date(0, 1, 1, 18, 22, 33, 0, expectedLoc),
}
for layout, tm := range kases {
for layout, tm := range cases {
t.Run(layout, func(t *testing.T) {
target, err := String2Time(layout, time.UTC, expectedLoc)
assert.NoError(t, err)