2016-12-26 53 views
-2

如何在GO中解析相對日期時間?相對日期解析

相對日期的示例:

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

所以格式是DAY (in the past) at TIME。我想下面的例子:

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

demo

時間被正確解析,但天/日期被忽略......

+0

'Monday'無需進一步日期參考是在分析器的眼睛沒有意義的,因此它被丟棄。哪個星期一?你不會爲此編寫自己更復雜的解析器。 –

+0

@Not_a_Golfer:過去的第一個星期一,我已經在這個問題中寫道:'所以格式是「天(過去)在TIME」。我嘗試了下一個例子:' –

+0

是的,但你能告訴解析器嗎?不! –

回答

1

擴大對我的評論:

只是Monday沒有進一步日期引用在解析器的眼中是沒有意義的,所以它被丟棄。哪個星期一?解析器是嚴格的,不是模糊的。假設星期一指的是本週,這不是一個這樣的解析器可以做的事情。你不會爲此編寫自己更復雜的解析器。

所以它必須是沿着這些路線 - 一個相對模糊的一天,一個真正的日期轉換,並取代一個功能,在原來的表達,而另一個是分析整個事情:

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

第二個函數獲取模糊時間,找到一天,解析它並返回。我不會去實現它,只是在註釋中寫什麼要做到:

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

我調整的東西,我寫了一段時間後,並鞏固了這個示例代碼:

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

它返回前一個targetDay的相對於現在的日期,將其添加到timeOfDay,假設timeOfDay包含小時,分鐘和秒以及年,月和日的零時間值,它將爲您提供合適的答案。

這不是很靈活,但我相信它適合你的例子相當好。雖然它沒有涉及「明天」,「昨天」或「下週六」等相關術語。

playground中的可運行版本。

0

定製解析器:

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