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)関数を書きましたが、完全に正しく動作していません。 (実際、ほとんどの場合、時間範囲が数日にわたって交差する2番目のケースが壊れています。元の部分は機能していました。
より良い(できれば組み込みの)方法があれば、私はそれについて聞きたいです!
注:ほんの一例として、この関数を使用して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で時間情報を操作するには、 time パッケージを使用します。
時刻は、Before、After、およびEqualメソッドを使用して比較できます。 Subメソッドは2つのインスタントを減算し、Durationを生成します。 Addメソッドは、TimeとDurationを追加して、Timeを生成します。
再生 例:
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, ".")
}
}
2回の比較のために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)
プログラムの出力:
Lifespan is 3h0m0s
間隔の終わりが「2017-01-01から2017-01-16の終日」のような時間のない日付の場合、間隔を23時間59分59秒に調整することをお勧めします。
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) {
...
}
最近のプロトコルでは、 golang time package documentation ごとにRFC3339の使用を好みます。
一般に、その形式を要求するサーバーにはRFC1123の代わりにRFC1123Zを使用する必要があり、新しいプロトコルにはRFC3339を優先する必要があります。 RFC822、RFC822Z、RFC1123、およびRFC1123Zはフォーマットに役立ちます。 time.Parseとともに使用すると、RFCで許可されているすべての時刻形式を受け入れません。
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).
以下は、文字列を日付に変換する私の問題を解決しました
パッケージメイン
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"