Files
sm-bm-plugin/models/temporal.go
Jakub Zych 71b848a376 Adopt SummerCMS v0.1.1 admin features
Datepickers on native time.Time / lagoon.Date fields, file uploads on
materials, readings and class sessions managed from the course form
(course_id made nullable).
2026-10-03 06:03:34 +02:00

61 lines
1.8 KiB
Go

package models
import (
"fmt"
"strings"
"time"
_ "time/tzdata" // Europe/Warsaw must resolve on hosts without zoneinfo.
"git.golem15.com/golem15/summercms/modules/lagoon"
)
// Location is the time zone the programme runs in. Timestamps are stored in
// UTC (TIMESTAMPTZ) and shown in this zone; a date or time typed without an
// offset is read in it.
var Location = mustLoadLocation("Europe/Warsaw")
func mustLoadLocation(name string) *time.Location {
loc, err := time.LoadLocation(name)
if err != nil {
panic(fmt.Sprintf("jz.bm: load location %s: %v", name, err))
}
return loc
}
// dateTimeLayouts are the forms ParseDateTime accepts. RFC 3339 carries its
// own offset; the others are wall-clock times in Location.
var dateTimeLayouts = []string{
"2006-01-02T15:04",
"2006-01-02 15:04",
"2006-01-02T15:04:05",
"2006-01-02 15:04:05",
}
// ParseDateTime reads an RFC 3339 timestamp, or a wall-clock time
// ("2026-10-03 08:00") in Location. The seed file uses these forms.
func ParseDateTime(s string) (time.Time, error) {
s = strings.TrimSpace(s)
if t, err := time.Parse(time.RFC3339, s); err == nil {
return t, nil
}
for _, layout := range dateTimeLayouts {
if t, err := time.ParseInLocation(layout, s, Location); err == nil {
return t, nil
}
}
return time.Time{}, fmt.Errorf("jz.bm: %q is not a date and time", s)
}
// ParseDate reads a YYYY-MM-DD calendar date.
func ParseDate(s string) (lagoon.Date, error) {
d, err := lagoon.ParseDate(strings.TrimSpace(s))
if err != nil {
return lagoon.Date{}, fmt.Errorf("jz.bm: %q is not a YYYY-MM-DD date", s)
}
return d, nil
}
// FormatDateTime is the API form of a timestamp: RFC 3339 in Location
// ("2026-10-03T08:00:00+02:00").
func FormatDateTime(t time.Time) string { return t.In(Location).Format(time.RFC3339) }