दिनांक / समय की तुलना कैसे करें


98

क्या गो में तारीख की तुलना करने का कोई विकल्प है? मुझे तारीख और समय के आधार पर डेटा को सॉर्ट करना होगा - स्वतंत्र रूप से। इसलिए मैं एक ऐसी वस्तु की अनुमति दे सकता हूं जो कि कुछ समय के भीतर होती है क्योंकि यह कई बार होती है। इस मॉडल में, मैं केवल सबसे पुरानी तारीख, सबसे कम समय / नवीनतम तारीख, नवीनतम समय और यूनिक्स () सेकंड का चयन नहीं कर सका। मैं वास्तव में किसी भी सुझाव की सराहना करेंगे।

अंततः, मैंने एक समय लिखा है कि स्ट्रिंग की तुलना करने के लिए मॉड्यूल की जाँच करें कि क्या एक समय सीमा के भीतर है। हालाँकि, यह अच्छी तरह से नहीं है; मुझे कुछ गैपिंग मुद्दे मिले हैं। मैं यहाँ सिर्फ मनोरंजन के लिए पोस्ट करूँगा, लेकिन मुझे उम्मीद है कि समय की तुलना करने का एक बेहतर तरीका है।

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, मैं एक भीतर समय (रेंज, समय) समारोह लिखा है, लेकिन यह पूरी तरह से सही ढंग से काम नहीं कर रहा है। (वास्तव में, ज्यादातर सिर्फ दूसरा मामला है, जहां दिनों के साथ एक समय सीमा पार हो जाती है। मूल भाग ने काम किया, मुझे बस एहसास हुआ कि स्थानीय से यूटीसी के लिए रूपांतरण करते समय मुझे इसके लिए ध्यान देना होगा।)

अगर वहाँ एक बेहतर (अधिमानतः बनाया गया) तरीका है, तो मुझे इसके बारे में सुनना अच्छा लगेगा!

नोट: बस एक उदाहरण के रूप में, मैंने इस फ़ंक्शन को जावास्क्रिप्ट में इस फ़ंक्शन के साथ हल किया:

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;
}

हालाँकि मैं वास्तव में यह फ़िल्टर सर्वर-साइड करना चाहता हूं।

जवाबों:


110

गो में समय की जानकारी के साथ काम करने के लिए समय पैकेज का उपयोग करें ।

समय से पहले, बाद और समान तरीकों का उपयोग करके समय की तुलना की जा सकती है। उप विधि दो अवधि को घटाती है, जो एक अवधि का निर्माण करती है। ऐड मेथड एक टाइम और ड्यूरेशन जोड़ता है, एक टाइम प्रोड्यूस करता है।

खेल का उदाहरण:

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, ".")
    }
}

1
शायद मैं पढ़ नहीं सकता, लेकिन मैंने समय की तुलना के बारे में वहां कुछ भी नहीं देखा। यदि यह वहां है, तो क्या आप मुझे एक सटीक लेख बता सकते हैं?
ईटोनफिल

12
Godoc.org/time#Time.Equal या godoc.org/time#Time के लिए प्रयास करें। सरल तुलना के लिए, या godoc.org/time#Time.Sub के बाद दो समय के बीच अंतर जानने के लिए।
औरबालमोहाल

1
"रिपोर्ट करता है कि क्या समय तत्काल यू के बाद है।" भयग्रस्त
डेमियन रोश

22

दो बार के बीच तुलना के लिए समय का उपयोग करें । ()

// 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


यह सबसे अच्छा जवाब है।
दोपहर

15

मामले के लिए जब आपके अंतराल के अंत की तारीख बिना घंटे के होती है जैसे "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) {
    ...
}

1
वास्तव में मुझे वर्तमान समय के साथ संग्रहीत टाइमस्टैम्प की तुलना करने की आवश्यकता थी।
PGP_Protector

1

हाल के प्रोटोकॉल RFC3339 प्रति गोलंग समय पैकेज प्रलेखन का उपयोग पसंद करते हैं ।

सामान्य रूप से RFC1123Z का उपयोग सर्वरों के लिए RFC1123 के बजाय किया जाना चाहिए जो उस प्रारूप पर जोर देते हैं, और नए प्रोटोकॉल के लिए RFC3339 को प्राथमिकता दी जानी चाहिए। RFC822, RFC822Z, RFC1123, और RFC1123Z स्वरूपण के लिए उपयोगी हैं; जब समय के साथ उपयोग किया जाता है। तब तक वे 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).

-1

निम्नलिखित ने स्ट्रिंग को तारीख में परिवर्तित करने की मेरी समस्या को हल किया

पैकेज मुख्य

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"

धन्‍यवाद धन्‍यवाद एडम स्‍मिथ


1
यह सब अच्छा है, लेकिन सवाल के साथ ऐसा करने के लिए बहुत कुछ नहीं है?
मथियास क्रुल

आप सही हैं @matthiaskrull यह तारीखों की तुलना के सवाल का जवाब नहीं देता है, लेकिन आंशिक रूप से तारीखों को आसानी से पार्स करने में मदद करता है।
सुर्यकृपा

ऐसा करने के लिए इस और अन्य लोगों के एक जोड़े। मैं सिर्फ यह कह रहा हूं कि टिप्पणियों में कुछ जोड़ना बेहतर होगा जो यादृच्छिक उपयोगी बिट्स के साथ उत्तर दे।
मथायस क्रुल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.