260
|
1 |
package toml |
|
2 |
|
|
3 |
import ( |
|
4 |
"fmt" |
|
5 |
"strings" |
|
6 |
"time" |
|
7 |
) |
|
8 |
|
|
9 |
// LocalDate represents a calendar day in no specific timezone. |
|
10 |
type LocalDate struct { |
|
11 |
Year int |
|
12 |
Month int |
|
13 |
Day int |
|
14 |
} |
|
15 |
|
|
16 |
// AsTime converts d into a specific time instance at midnight in zone. |
|
17 |
func (d LocalDate) AsTime(zone *time.Location) time.Time { |
|
18 |
return time.Date(d.Year, time.Month(d.Month), d.Day, 0, 0, 0, 0, zone) |
|
19 |
} |
|
20 |
|
|
21 |
// String returns RFC 3339 representation of d. |
|
22 |
func (d LocalDate) String() string { |
|
23 |
return fmt.Sprintf("%04d-%02d-%02d", d.Year, d.Month, d.Day) |
|
24 |
} |
|
25 |
|
|
26 |
// MarshalText returns RFC 3339 representation of d. |
|
27 |
func (d LocalDate) MarshalText() ([]byte, error) { |
|
28 |
return []byte(d.String()), nil |
|
29 |
} |
|
30 |
|
|
31 |
// UnmarshalText parses b using RFC 3339 to fill d. |
|
32 |
func (d *LocalDate) UnmarshalText(b []byte) error { |
|
33 |
res, err := parseLocalDate(b) |
|
34 |
if err != nil { |
|
35 |
return err |
|
36 |
} |
|
37 |
*d = res |
|
38 |
return nil |
|
39 |
} |
|
40 |
|
|
41 |
// LocalTime represents a time of day of no specific day in no specific |
|
42 |
// timezone. |
|
43 |
type LocalTime struct { |
|
44 |
Hour int // Hour of the day: [0; 24[ |
|
45 |
Minute int // Minute of the hour: [0; 60[ |
|
46 |
Second int // Second of the minute: [0; 60[ |
|
47 |
Nanosecond int // Nanoseconds within the second: [0, 1000000000[ |
|
48 |
Precision int // Number of digits to display for Nanosecond. |
|
49 |
} |
|
50 |
|
|
51 |
// String returns RFC 3339 representation of d. |
|
52 |
// If d.Nanosecond and d.Precision are zero, the time won't have a nanosecond |
|
53 |
// component. If d.Nanosecond > 0 but d.Precision = 0, then the minimum number |
|
54 |
// of digits for nanoseconds is provided. |
|
55 |
func (d LocalTime) String() string { |
|
56 |
s := fmt.Sprintf("%02d:%02d:%02d", d.Hour, d.Minute, d.Second) |
|
57 |
|
|
58 |
if d.Precision > 0 { |
|
59 |
s += fmt.Sprintf(".%09d", d.Nanosecond)[:d.Precision+1] |
|
60 |
} else if d.Nanosecond > 0 { |
|
61 |
// Nanoseconds are specified, but precision is not provided. Use the |
|
62 |
// minimum. |
|
63 |
s += strings.Trim(fmt.Sprintf(".%09d", d.Nanosecond), "0") |
|
64 |
} |
|
65 |
|
|
66 |
return s |
|
67 |
} |
|
68 |
|
|
69 |
// MarshalText returns RFC 3339 representation of d. |
|
70 |
func (d LocalTime) MarshalText() ([]byte, error) { |
|
71 |
return []byte(d.String()), nil |
|
72 |
} |
|
73 |
|
|
74 |
// UnmarshalText parses b using RFC 3339 to fill d. |
|
75 |
func (d *LocalTime) UnmarshalText(b []byte) error { |
|
76 |
res, left, err := parseLocalTime(b) |
|
77 |
if err == nil && len(left) != 0 { |
|
78 |
err = newDecodeError(left, "extra characters") |
|
79 |
} |
|
80 |
if err != nil { |
|
81 |
return err |
|
82 |
} |
|
83 |
*d = res |
|
84 |
return nil |
|
85 |
} |
|
86 |
|
|
87 |
// LocalDateTime represents a time of a specific day in no specific timezone. |
|
88 |
type LocalDateTime struct { |
|
89 |
LocalDate |
|
90 |
LocalTime |
|
91 |
} |
|
92 |
|
|
93 |
// AsTime converts d into a specific time instance in zone. |
|
94 |
func (d LocalDateTime) AsTime(zone *time.Location) time.Time { |
|
95 |
return time.Date(d.Year, time.Month(d.Month), d.Day, d.Hour, d.Minute, d.Second, d.Nanosecond, zone) |
|
96 |
} |
|
97 |
|
|
98 |
// String returns RFC 3339 representation of d. |
|
99 |
func (d LocalDateTime) String() string { |
|
100 |
return d.LocalDate.String() + "T" + d.LocalTime.String() |
|
101 |
} |
|
102 |
|
|
103 |
// MarshalText returns RFC 3339 representation of d. |
|
104 |
func (d LocalDateTime) MarshalText() ([]byte, error) { |
|
105 |
return []byte(d.String()), nil |
|
106 |
} |
|
107 |
|
|
108 |
// UnmarshalText parses b using RFC 3339 to fill d. |
|
109 |
func (d *LocalDateTime) UnmarshalText(data []byte) error { |
|
110 |
res, left, err := parseLocalDateTime(data) |
|
111 |
if err == nil && len(left) != 0 { |
|
112 |
err = newDecodeError(left, "extra characters") |
|
113 |
} |
|
114 |
if err != nil { |
|
115 |
return err |
|
116 |
} |
|
117 |
|
|
118 |
*d = res |
|
119 |
return nil |
|
120 |
} |