123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- package toml
- import (
- "fmt"
- "strings"
- "time"
- "github.com/pelletier/go-toml/v2/unstable"
- )
- // LocalDate represents a calendar day in no specific timezone.
- type LocalDate struct {
- Year int
- Month int
- Day int
- }
- // AsTime converts d into a specific time instance at midnight in zone.
- func (d LocalDate) AsTime(zone *time.Location) time.Time {
- return time.Date(d.Year, time.Month(d.Month), d.Day, 0, 0, 0, 0, zone)
- }
- // String returns RFC 3339 representation of d.
- func (d LocalDate) String() string {
- return fmt.Sprintf("%04d-%02d-%02d", d.Year, d.Month, d.Day)
- }
- // MarshalText returns RFC 3339 representation of d.
- func (d LocalDate) MarshalText() ([]byte, error) {
- return []byte(d.String()), nil
- }
- // UnmarshalText parses b using RFC 3339 to fill d.
- func (d *LocalDate) UnmarshalText(b []byte) error {
- res, err := parseLocalDate(b)
- if err != nil {
- return err
- }
- *d = res
- return nil
- }
- // LocalTime represents a time of day of no specific day in no specific
- // timezone.
- type LocalTime struct {
- Hour int // Hour of the day: [0; 24[
- Minute int // Minute of the hour: [0; 60[
- Second int // Second of the minute: [0; 60[
- Nanosecond int // Nanoseconds within the second: [0, 1000000000[
- Precision int // Number of digits to display for Nanosecond.
- }
- // String returns RFC 3339 representation of d.
- // If d.Nanosecond and d.Precision are zero, the time won't have a nanosecond
- // component. If d.Nanosecond > 0 but d.Precision = 0, then the minimum number
- // of digits for nanoseconds is provided.
- func (d LocalTime) String() string {
- s := fmt.Sprintf("%02d:%02d:%02d", d.Hour, d.Minute, d.Second)
- if d.Precision > 0 {
- s += fmt.Sprintf(".%09d", d.Nanosecond)[:d.Precision+1]
- } else if d.Nanosecond > 0 {
- // Nanoseconds are specified, but precision is not provided. Use the
- // minimum.
- s += strings.Trim(fmt.Sprintf(".%09d", d.Nanosecond), "0")
- }
- return s
- }
- // MarshalText returns RFC 3339 representation of d.
- func (d LocalTime) MarshalText() ([]byte, error) {
- return []byte(d.String()), nil
- }
- // UnmarshalText parses b using RFC 3339 to fill d.
- func (d *LocalTime) UnmarshalText(b []byte) error {
- res, left, err := parseLocalTime(b)
- if err == nil && len(left) != 0 {
- err = unstable.NewParserError(left, "extra characters")
- }
- if err != nil {
- return err
- }
- *d = res
- return nil
- }
- // LocalDateTime represents a time of a specific day in no specific timezone.
- type LocalDateTime struct {
- LocalDate
- LocalTime
- }
- // AsTime converts d into a specific time instance in zone.
- func (d LocalDateTime) AsTime(zone *time.Location) time.Time {
- return time.Date(d.Year, time.Month(d.Month), d.Day, d.Hour, d.Minute, d.Second, d.Nanosecond, zone)
- }
- // String returns RFC 3339 representation of d.
- func (d LocalDateTime) String() string {
- return d.LocalDate.String() + "T" + d.LocalTime.String()
- }
- // MarshalText returns RFC 3339 representation of d.
- func (d LocalDateTime) MarshalText() ([]byte, error) {
- return []byte(d.String()), nil
- }
- // UnmarshalText parses b using RFC 3339 to fill d.
- func (d *LocalDateTime) UnmarshalText(data []byte) error {
- res, left, err := parseLocalDateTime(data)
- if err == nil && len(left) != 0 {
- err = unstable.NewParserError(left, "extra characters")
- }
- if err != nil {
- return err
- }
- *d = res
- return nil
- }
|