inital commit
This commit is contained in:
64
time.go
Normal file
64
time.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package fa
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// faDateLayouts lists every layout FA has been observed emitting in
|
||||
// title= attributes of date elements. Tried in order.
|
||||
var faDateLayouts = []string{
|
||||
"January 2, 2006 03:04:05 PM", // "March 23, 2026 09:01:08 AM" current beta popup_date title
|
||||
"January 2, 2006 3:04:05 PM",
|
||||
"Jan 2, 2006 03:04:05 PM", // 3-letter month variant
|
||||
"Jan 2, 2006 3:04:05 PM",
|
||||
"Jan 2, 2006 03:04 PM", // legacy beta layout (no seconds)
|
||||
"Jan 2, 2006 3:04 PM",
|
||||
"2006-01-02T15:04:05Z07:00",
|
||||
time.RFC3339,
|
||||
}
|
||||
|
||||
// ParseFADate parses a FurAffinity-formatted date string. FA renders dates
|
||||
// either as a "popup" with the full timestamp in a title attribute, or as a
|
||||
// relative phrase ("5 hours ago") in the visible text. Callers should pass
|
||||
// the title attribute when available.
|
||||
//
|
||||
// FA does not include timezone information in its displayed format; the site
|
||||
// uses server-local time historically labelled as UTC-7. We treat parsed
|
||||
// values as UTC because that is what the SDK consistently exposes callers
|
||||
// who need a wall-clock display should convert.
|
||||
func ParseFADate(s string) (time.Time, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return time.Time{}, fmt.Errorf("parse fa date: empty string")
|
||||
}
|
||||
cleaned := stripOrdinals(s)
|
||||
for _, layout := range faDateLayouts {
|
||||
if t, err := time.ParseInLocation(layout, cleaned, time.UTC); err == nil {
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
return time.Time{}, fmt.Errorf("parse fa date %q: no matching layout", s)
|
||||
}
|
||||
|
||||
// stripOrdinals removes English ordinal suffixes (st, nd, rd, th) from a date
|
||||
// string so it can be parsed by Go's reference layout. "Mar 17th, 2026" →
|
||||
// "Mar 17, 2026".
|
||||
func stripOrdinals(s string) string {
|
||||
var b strings.Builder
|
||||
b.Grow(len(s))
|
||||
for i := 0; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if (c >= '0' && c <= '9') && i+2 < len(s) {
|
||||
next2 := strings.ToLower(s[i+1 : i+3])
|
||||
if next2 == "st" || next2 == "nd" || next2 == "rd" || next2 == "th" {
|
||||
b.WriteByte(c)
|
||||
i += 2
|
||||
continue
|
||||
}
|
||||
}
|
||||
b.WriteByte(c)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
Reference in New Issue
Block a user