116

Goで日付比較を行うオプションはありますか? 日付と時刻に基づいてデータを個別に並べ替える必要があります。したがって、ある範囲の時間内に発生する限り、ある範囲の日付内に発生するオブジェクトを許可する場合があります。このモデルでは、最古の日付、最年少の時刻/最新の日付、最新の時刻、および 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 番目のケースが壊れています。元の部分は機能していましたが、ローカルから 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;
}

しかし、私は本当にこのフィルターをサーバー側でやりたいと思っています。

4

7 に答える 7

29

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

http://play.golang.org/p/bbxeTtd4L6

于 2015-12-05T02:25:23.670 に答える