localtime.go 3.2 KB

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