mirror of
https://github.com/dstotijn/go-notion.git
synced 2024-12-04 10:24:57 +02:00
96 lines
2.1 KiB
Go
96 lines
2.1 KiB
Go
package notion
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
// Length of a date string, e.g. `2006-01-02`.
|
|
const dateLength = 10
|
|
|
|
// DateTimeFormat is used when calling time.Parse, using RFC3339 with microsecond
|
|
// precision, which is what the Notion API returns in JSON response data.
|
|
const DateTimeFormat = "2006-01-02T15:04:05.999Z07:00"
|
|
|
|
// DateTime represents a Notion date property with optional time.
|
|
type DateTime struct {
|
|
time.Time
|
|
hasTime bool
|
|
}
|
|
|
|
// ParseDateTime parses an RFC3339 formatted string with optional time.
|
|
func ParseDateTime(value string) (DateTime, error) {
|
|
if len(value) > len(DateTimeFormat) {
|
|
return DateTime{}, errors.New("invalid datetime string")
|
|
}
|
|
|
|
t, err := time.Parse(DateTimeFormat[:len(value)], value)
|
|
if err != nil {
|
|
return DateTime{}, err
|
|
}
|
|
|
|
dt := DateTime{
|
|
Time: t,
|
|
hasTime: len(value) > dateLength,
|
|
}
|
|
|
|
return dt, nil
|
|
}
|
|
|
|
// UnmarshalJSON implements json.Unmarshaler.
|
|
func (dt *DateTime) UnmarshalJSON(b []byte) error {
|
|
if len(b) < 2 {
|
|
return errors.New("invalid datetime string")
|
|
}
|
|
|
|
parsed, err := ParseDateTime(string(b[1 : len(b)-1]))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*dt = parsed
|
|
|
|
return nil
|
|
}
|
|
|
|
// MarshalJSON implements json.Marshaler. It returns an RFC399 formatted string,
|
|
// using microsecond precision ()
|
|
func (dt DateTime) MarshalJSON() ([]byte, error) {
|
|
if dt.hasTime {
|
|
return json.Marshal(dt.Time)
|
|
}
|
|
return []byte(`"` + dt.Time.Format(DateTimeFormat[:dateLength]) + `"`), nil
|
|
}
|
|
|
|
// NewDateTime returns a new DateTime. If `haseTime` is true, time is included
|
|
// when encoding to JSON.
|
|
func NewDateTime(t time.Time, hasTime bool) DateTime {
|
|
var tt time.Time
|
|
|
|
if hasTime {
|
|
tt = t
|
|
} else {
|
|
tt = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC)
|
|
}
|
|
|
|
return DateTime{
|
|
Time: tt,
|
|
hasTime: hasTime,
|
|
}
|
|
}
|
|
|
|
// HasTime returns true if the datetime was parsed from a string that included time.
|
|
func (dt *DateTime) HasTime() bool {
|
|
return dt.hasTime
|
|
}
|
|
|
|
// Equal returns true if both DateTime values have equal underlying time.Time and
|
|
// hasTime fields.
|
|
func (dt DateTime) Equal(value DateTime) bool {
|
|
if !dt.Time.Equal(value.Time) {
|
|
return false
|
|
}
|
|
return dt.hasTime == value.hasTime
|
|
}
|