2016-12-26 4 views
-2

Wie man relative Datetime in GO analysiert?Relatives Datum Parsing

Beispiel für relative Daten:

today at 9:17 AM 
yesterday at 9:58 PM 
Saturday at 9:44 PM 
Wednesday at 11:01 AM 

So ist Format DAY (in the past) at TIME. Ich habe versucht, nächstes Beispiel:

const longForm = "Monday at 3:04 PM" 
t, _ := time.Parse(longForm, "Saturday at 3:50 PM") 
fmt.Println(t) 

demo

Zeit korrekt analysiert wird, aber Tag/Datum ignoriert ...

+0

'Monday' ohne weitere aktuelle Referenz ist in den Augen des Parsers bedeutungslos, so wird sie verworfen. Welcher Montag? Sie werden dafür keinen eigenen komplexeren Parser schreiben. –

+0

@Not_a_Golfer: ersten Montag in der Vergangenheit, schrieb ich bereits, dass in der Frage: 'So Format ist" DAY (in der Vergangenheit) um TIME ". Ich habe folgendes Beispiel versucht: ' –

+0

Ja, aber kannst du dem Parser das sagen? Nee! –

Antwort

1

auf meinen Kommentar Expanding:

Gerade Monday ohne weitere Da die Datumsreferenz in den Augen des Parsers bedeutungslos ist, wird sie verworfen. Welcher Montag? Der Parser ist streng, nicht unscharf. Angenommen, Montag bezieht sich auf die aktuelle Woche, ist etwas, was ein solcher Parser nicht kann. Sie werden dafür keinen eigenen komplexeren Parser schreiben.

So würde es in dieser Richtung sein - eine Funktion, die einen relativ unscharf Tag zu einem echten Datum konvertiert, und ersetzt den in den ursprünglichen Ausdruck, und ein anderer, der die ganze Sache parst:

const dateFormat = "2006-01-02" 
const longForm = "2006-01-02 at 3:04 PM" 

func parseFuzzyDate(fuzzyTime string) (time.Time, error) { 

    formattedTime, err := parseDayAndReplaceIt(fuzzyTime) 
    if err != nil { 
     return nil, err 
    } 

    return time.Parse(longForm, formattedTime) 
} 

und die zweite Funktion bekommt die unscharfe Zeit, findet den Tag, analysiert ihn und kehrt zurück. Ich werde es nicht implementieren, einfach in den Kommentaren schreiben, was getan werden sollte:

func parseDayAndReplaceIt(fuzzyTime string) (string, error) { 
    // 1. Extract the day 

    // 2. Parse weekday names to relative time 

    // 3. if it's not a weekday name, parse things like "tomorrow" "yesterday" 

    // 4. replace the day string in the original fuzzyTime with a formatted date that the parser can understand 

    // 5. return the formatted date 
} 
0

ich etwas gezwickt, dass ich eine Weile zurück, schrieb und konsolidiert sie in diesem Beispielcode:

func lastDateOf(targetDay time.Weekday, timeOfDay time.Time) time.Time { 
    const oneDay = 24 * time.Hour 
    var dayIndex time.Duration 

    //dayIndex -= oneDay 
    for { 
     if time.Now().Add(dayIndex).Weekday() == targetDay { 
      y, m, d := time.Now().Add(dayIndex).Date() 
      return timeOfDay.AddDate(y, int(m)-1, d-1) 
     } 
     dayIndex -= oneDay 
    } 
} 

Es gibt das Datum des vorherigen targetDay, das zu timeOfDay hinzugefügt wurde, unter der Annahme an, dass timeOfDay aus Stunden, Minuten und Sekunden besteht und die Nullzeitwerte für Jahr, Monat und Tag eine geeignete Antwort liefern.

Es ist nicht sehr flexibel, aber ich glaube, es passt gut zu Ihrem Beispiel. Relativere Begriffe wie "morgen", "gestern" oder "nächsten Samstag" werden nicht behandelt.

Runnable-Version in der .

0

Benutzerdefinierte Parser:

func RelativeDateParse(s string) (time.Time, error) { 
    for n := 0; n < 7; n++ { 
     day := time.Now().AddDate(0, 0, -n) 
     dayName := day.Format("Monday") 
     switch n { 
     case 0: 
      dayName = "today" 
     case 1: 
      dayName = "yesterday" 
     } 
     s = strings.Replace(s, dayName + " at", day.Format("2006-01-02"), -1) 
    } 
    return time.Parse("2006-01-02 3:04 PM", s) 
} 

demo