micro_time.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package v1
  14. import (
  15. "encoding/json"
  16. "time"
  17. "github.com/google/gofuzz"
  18. )
  19. const RFC3339Micro = "2006-01-02T15:04:05.000000Z07:00"
  20. // MicroTime is version of Time with microsecond level precision.
  21. //
  22. // +protobuf.options.marshal=false
  23. // +protobuf.as=Timestamp
  24. // +protobuf.options.(gogoproto.goproto_stringer)=false
  25. type MicroTime struct {
  26. time.Time `protobuf:"-"`
  27. }
  28. // DeepCopy returns a deep-copy of the MicroTime value. The underlying time.Time
  29. // type is effectively immutable in the time API, so it is safe to
  30. // copy-by-assign, despite the presence of (unexported) Pointer fields.
  31. func (t *MicroTime) DeepCopyInto(out *MicroTime) {
  32. *out = *t
  33. }
  34. // String returns the representation of the time.
  35. func (t MicroTime) String() string {
  36. return t.Time.String()
  37. }
  38. // NewMicroTime returns a wrapped instance of the provided time
  39. func NewMicroTime(time time.Time) MicroTime {
  40. return MicroTime{time}
  41. }
  42. // DateMicro returns the MicroTime corresponding to the supplied parameters
  43. // by wrapping time.Date.
  44. func DateMicro(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) MicroTime {
  45. return MicroTime{time.Date(year, month, day, hour, min, sec, nsec, loc)}
  46. }
  47. // NowMicro returns the current local time.
  48. func NowMicro() MicroTime {
  49. return MicroTime{time.Now()}
  50. }
  51. // IsZero returns true if the value is nil or time is zero.
  52. func (t *MicroTime) IsZero() bool {
  53. if t == nil {
  54. return true
  55. }
  56. return t.Time.IsZero()
  57. }
  58. // Before reports whether the time instant t is before u.
  59. func (t *MicroTime) Before(u *MicroTime) bool {
  60. return t.Time.Before(u.Time)
  61. }
  62. // Equal reports whether the time instant t is equal to u.
  63. func (t *MicroTime) Equal(u *MicroTime) bool {
  64. return t.Time.Equal(u.Time)
  65. }
  66. // BeforeTime reports whether the time instant t is before second-lever precision u.
  67. func (t *MicroTime) BeforeTime(u *Time) bool {
  68. return t.Time.Before(u.Time)
  69. }
  70. // EqualTime reports whether the time instant t is equal to second-lever precision u.
  71. func (t *MicroTime) EqualTime(u *Time) bool {
  72. return t.Time.Equal(u.Time)
  73. }
  74. // UnixMicro returns the local time corresponding to the given Unix time
  75. // by wrapping time.Unix.
  76. func UnixMicro(sec int64, nsec int64) MicroTime {
  77. return MicroTime{time.Unix(sec, nsec)}
  78. }
  79. // UnmarshalJSON implements the json.Unmarshaller interface.
  80. func (t *MicroTime) UnmarshalJSON(b []byte) error {
  81. if len(b) == 4 && string(b) == "null" {
  82. t.Time = time.Time{}
  83. return nil
  84. }
  85. var str string
  86. err := json.Unmarshal(b, &str)
  87. if err != nil {
  88. return err
  89. }
  90. pt, err := time.Parse(RFC3339Micro, str)
  91. if err != nil {
  92. return err
  93. }
  94. t.Time = pt.Local()
  95. return nil
  96. }
  97. // UnmarshalQueryParameter converts from a URL query parameter value to an object
  98. func (t *MicroTime) UnmarshalQueryParameter(str string) error {
  99. if len(str) == 0 {
  100. t.Time = time.Time{}
  101. return nil
  102. }
  103. // Tolerate requests from older clients that used JSON serialization to build query params
  104. if len(str) == 4 && str == "null" {
  105. t.Time = time.Time{}
  106. return nil
  107. }
  108. pt, err := time.Parse(RFC3339Micro, str)
  109. if err != nil {
  110. return err
  111. }
  112. t.Time = pt.Local()
  113. return nil
  114. }
  115. // MarshalJSON implements the json.Marshaler interface.
  116. func (t MicroTime) MarshalJSON() ([]byte, error) {
  117. if t.IsZero() {
  118. // Encode unset/nil objects as JSON's "null".
  119. return []byte("null"), nil
  120. }
  121. return json.Marshal(t.UTC().Format(RFC3339Micro))
  122. }
  123. // OpenAPISchemaType is used by the kube-openapi generator when constructing
  124. // the OpenAPI spec of this type.
  125. //
  126. // See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
  127. func (_ MicroTime) OpenAPISchemaType() []string { return []string{"string"} }
  128. // OpenAPISchemaFormat is used by the kube-openapi generator when constructing
  129. // the OpenAPI spec of this type.
  130. func (_ MicroTime) OpenAPISchemaFormat() string { return "date-time" }
  131. // MarshalQueryParameter converts to a URL query parameter value
  132. func (t MicroTime) MarshalQueryParameter() (string, error) {
  133. if t.IsZero() {
  134. // Encode unset/nil objects as an empty string
  135. return "", nil
  136. }
  137. return t.UTC().Format(RFC3339Micro), nil
  138. }
  139. // Fuzz satisfies fuzz.Interface.
  140. func (t *MicroTime) Fuzz(c fuzz.Continue) {
  141. if t == nil {
  142. return
  143. }
  144. // Allow for about 1000 years of randomness. Accurate to a tenth of
  145. // micro second. Leave off nanoseconds because JSON doesn't
  146. // represent them so they can't round-trip properly.
  147. t.Time = time.Unix(c.Rand.Int63n(1000*365*24*60*60), 1000*c.Rand.Int63n(1000000))
  148. }
  149. var _ fuzz.Interface = &MicroTime{}