Skip to content

Instantly share code, notes, and snippets.

@krzko
Created September 14, 2023 05:41
Show Gist options
  • Save krzko/081082daa04cbea88035845244ef75e3 to your computer and use it in GitHub Desktop.
Save krzko/081082daa04cbea88035845244ef75e3 to your computer and use it in GitHub Desktop.
Example natural languag date sort
package main
import (
"fmt"
"regexp"
"sort"
"strconv"
"time"
)
// Define a regex to capture the day, month, and year
var dateRegex = regexp.MustCompile(`(\d{1,2})\s+([A-Za-z]+)\s+(\d{4})`)
// Mapping month abbreviations to their numeric value
var monthMap = map[string]int{
"Jan": 1,
"Feb": 2,
"Mar": 3,
"Apr": 4,
"May": 5,
"Jun": 6,
"Jul": 7,
"Aug": 8,
"Sep": 9,
"Sept": 9, // Sept typo example
"Oct": 10,
"Nov": 11,
"Dec": 12,
}
// Convert a string date to time.Time for comparison
func parseDate(dateStr string) (time.Time, error) {
matches := dateRegex.FindStringSubmatch(dateStr)
if matches == nil {
return time.Time{}, fmt.Errorf("invalid date format")
}
day, _ := strconv.Atoi(matches[1])
month, ok := monthMap[matches[2]]
if !ok {
return time.Time{}, fmt.Errorf("invalid month format")
}
year, _ := strconv.Atoi(matches[3])
return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC), nil
}
// Sort a list of dates in natural order
func sortDates(dates []string) ([]string, error) {
sort.Slice(dates, func(i, j int) bool {
dateI, err := parseDate(dates[i])
if err != nil {
return false
}
dateJ, err := parseDate(dates[j])
if err != nil {
return true
}
return dateI.Before(dateJ)
})
return dates, nil
}
func main() {
dates := []string{
"16 Sep 2023",
"10 Sep 2023",
"01 Jan 1970",
"13 Sep 2023",
"15 Sept 2023",
"12 Mar 1990",
"14 Sep 2023",
}
sortedDates, err := sortDates(dates)
if err != nil {
fmt.Println(err)
return
}
for _, date := range sortedDates {
fmt.Println(date)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment