Golang의 날짜 / 시간 비교
Golang에서 날짜 비교를 수행하는 옵션이 있습니까? 날짜와 시간을 기준으로 독립적으로 데이터를 정렬해야합니다. 따라서 시간 범위 내에서도 발생하는 한 날짜 범위 내에서 발생하는 개체를 허용 할 수 있습니다. 이 모델에서는 단순히 가장 오래된 날짜, 가장 어린 시간 / 최근 날짜, 최신 시간 및 Unix () 초를 선택하여 비교할 수는 없습니다. 어떤 제안이라도 정말 감사하겠습니다.
궁극적으로 시간이 범위 내에 있는지 확인하기 위해 시간 구문 분석 문자열 비교 모듈을 작성했습니다. 그러나 이것은 잘되지 않습니다. 몇 가지 문제가 있습니다. 재미를 위해 여기에 게시 할 것이지만 시간을 비교하는 더 좋은 방법이 있기를 바랍니다.
package main
import (
"strconv"
"strings"
)
func tryIndex(arr []string, index int, def string) string {
if index <= len(arr)-1 {
return arr[index]
}
return def
}
/*
* Takes two strings of format "hh:mm:ss" and compares them.
* Takes a function to compare individual sections (split by ":").
* Note: strings can actually be formatted like "h", "hh", "hh:m",
* "hh:mm", etc. Any missing parts will be added lazily.
*/
func timeCompare(a, b string, compare func(int, int) (bool, bool)) bool {
aArr := strings.Split(a, ":")
bArr := strings.Split(b, ":")
// Catches margins.
if (b == a) {
return true
}
for i := range aArr {
aI, _ := strconv.Atoi(tryIndex(aArr, i, "00"))
bI, _ := strconv.Atoi(tryIndex(bArr, i, "00"))
res, flag := compare(aI, bI)
if res {
return true
} else if flag { // Needed to catch case where a > b and a is the lower limit
return false
}
}
return false
}
func timeGreaterEqual(a, b int) (bool, bool) {return a > b, a < b}
func timeLesserEqual(a, b int) (bool, bool) {return a < b, a > b}
/*
* Returns true for two strings formmated "hh:mm:ss".
* Note: strings can actually be formatted like "h", "hh", "hh:m",
* "hh:mm", etc. Any missing parts will be added lazily.
*/
func withinTime(timeRange, time string) bool {
rArr := strings.Split(timeRange, "-")
if timeCompare(rArr[0], rArr[1], timeLesserEqual) {
afterStart := timeCompare(rArr[0], time, timeLesserEqual)
beforeEnd := timeCompare(rArr[1], time, timeGreaterEqual)
return afterStart && beforeEnd
}
// Catch things like `timeRange := "22:00:00-04:59:59"` which will happen
// with UTC conversions from local time.
// THIS IS THE BROKEN PART I BELIEVE
afterStart := timeCompare(rArr[0], time, timeLesserEqual)
beforeEnd := timeCompare(rArr[1], time, timeGreaterEqual)
return afterStart || beforeEnd
}
그래서 TLDR, withinTimeRange (range, time) 함수를 작성했지만 완전히 올바르게 작동하지 않습니다. (사실, 대부분의 경우 시간 범위가 며칠에 걸쳐 교차하는 두 번째 경우에 불과합니다. 원래 부분은 작동했지만 로컬에서 UTC로 변환 할 때이를 고려해야한다는 것을 깨달았습니다.)
더 나은 (기본적으로 내장 된) 방법이 있다면 그것에 대해 듣고 싶습니다!
참고 : 예를 들어이 함수를 사용하여 Javascript에서이 문제를 해결했습니다.
function withinTime(start, end, time) {
var s = Date.parse("01/01/2011 "+start);
var e = Date.parse("01/0"+(end=="24:00:00"?"2":"1")+"/2011 "+(end=="24:00:00"?"00:00:00":end));
var t = Date.parse("01/01/2011 "+time);
return s <= t && e >= t;
}
그러나 나는이 필터를 서버 측에서 정말로 원합니다.
시간 패키지를 사용하여 Go에서 시간 정보로 작업하십시오.
시간 순간은 Before, After 및 Equal 방법을 사용하여 비교할 수 있습니다. Sub 메서드는 두 순간을 빼서 Duration을 생성합니다. Add 메서드는 시간과 기간을 추가하여 시간을 생성합니다.
플레이 예 :
package main
import (
"fmt"
"time"
)
func inTimeSpan(start, end, check time.Time) bool {
return check.After(start) && check.Before(end)
}
func main() {
start, _ := time.Parse(time.RFC822, "01 Jan 15 10:00 UTC")
end, _ := time.Parse(time.RFC822, "01 Jan 16 10:00 UTC")
in, _ := time.Parse(time.RFC822, "01 Jan 15 20:00 UTC")
out, _ := time.Parse(time.RFC822, "01 Jan 17 10:00 UTC")
if inTimeSpan(start, end, in) {
fmt.Println(in, "is between", start, "and", end, ".")
}
if !inTimeSpan(start, end, out) {
fmt.Println(out, "is not between", start, "and", end, ".")
}
}
For comparison between two times use time.Sub()
// utc life
loc, _ := time.LoadLocation("UTC")
// setup a start and end time
createdAt := time.Now().In(loc).Add(1 * time.Hour)
expiresAt := time.Now().In(loc).Add(4 * time.Hour)
// get the diff
diff := expiresAt.Sub(createdAt)
fmt.Printf("Lifespan is %+v", diff)
The program outputs:
Lifespan is 3h0m0s
http://play.golang.org/p/bbxeTtd4L6
For case when your interval's end it's date without hours like "from 2017-01-01 to whole day of 2017-01-16" it's better to adjust interval's to 23 hours 59 minutes and 59 seconds like:
end = end.Add(time.Duration(23*time.Hour) + time.Duration(59*time.Minute) + time.Duration(59*time.Second))
if now.After(start) && now.Before(end) {
...
}
Recent protocols prefer usage of RFC3339 per golang time package documentation.
In general RFC1123Z should be used instead of RFC1123 for servers that insist on that format, and RFC3339 should be preferred for new protocols. RFC822, RFC822Z, RFC1123, and RFC1123Z are useful for formatting; when used with time.Parse they do not accept all the time formats permitted by the RFCs.
cutOffTime, _ := time.Parse(time.RFC3339, "2017-08-30T13:35:00Z")
// POSTDATE is a date time field in DB (datastore)
query := datastore.NewQuery("db").Filter("POSTDATE >=", cutOffTime).
The following solved my problem of converting string into date
package main
import (
"fmt"
"time"
)
func main() {
value := "Thu, 05/19/11, 10:47PM"
// Writing down the way the standard time would look like formatted our way
layout := "Mon, 01/02/06, 03:04PM"
t, _ := time.Parse(layout, value)
fmt.Println(t)
}
// => "Thu May 19 22:47:00 +0000 2011"
참고URL : https://stackoverflow.com/questions/20924303/date-time-comparison-in-golang
'program tip' 카테고리의 다른 글
SqlParameter는 이미 다른 SqlParameterCollection에 포함되어 있습니다. using () {} 치트를 사용합니까? (0) | 2020.10.17 |
---|---|
최대 장치 너비 또는 최대 너비를 사용해야합니까? (0) | 2020.10.17 |
Rails 3 + activerecord, 조건을 충족하는 모든 레코드에 대해 단일 필드를 "대량 업데이트"하는 가장 좋은 방법 (0) | 2020.10.16 |
Xcode 4 + iOS 4.3 : "아카이브 유형에 대한 Packager가 없습니다." (0) | 2020.10.16 |
Java가 인터페이스에서 개인 멤버를 허용하지 않는 이유는 무엇입니까? (0) | 2020.10.16 |