本站源代码
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

204 lines
5.2KB

  1. // Copyright 2015 go-swagger maintainers
  2. //
  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. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package strfmt
  15. import (
  16. "database/sql/driver"
  17. "encoding/json"
  18. "errors"
  19. "fmt"
  20. "regexp"
  21. "strings"
  22. "time"
  23. "go.mongodb.org/mongo-driver/bson"
  24. )
  25. func init() {
  26. dt := DateTime{}
  27. Default.Add("datetime", &dt, IsDateTime)
  28. }
  29. // IsDateTime returns true when the string is a valid date-time
  30. func IsDateTime(str string) bool {
  31. if len(str) < 4 {
  32. return false
  33. }
  34. s := strings.Split(strings.ToLower(str), "t")
  35. if len(s) < 2 || !IsDate(s[0]) {
  36. return false
  37. }
  38. matches := rxDateTime.FindAllStringSubmatch(s[1], -1)
  39. if len(matches) == 0 || len(matches[0]) == 0 {
  40. return false
  41. }
  42. m := matches[0]
  43. res := m[1] <= "23" && m[2] <= "59" && m[3] <= "59"
  44. return res
  45. }
  46. const (
  47. // RFC3339Millis represents a ISO8601 format to millis instead of to nanos
  48. RFC3339Millis = "2006-01-02T15:04:05.000Z07:00"
  49. // RFC3339Micro represents a ISO8601 format to micro instead of to nano
  50. RFC3339Micro = "2006-01-02T15:04:05.000000Z07:00"
  51. // ISO8601LocalTime represents a ISO8601 format to ISO8601 in local time (no timezone)
  52. ISO8601LocalTime = "2006-01-02T15:04:05"
  53. // DateTimePattern pattern to match for the date-time format from http://tools.ietf.org/html/rfc3339#section-5.6
  54. DateTimePattern = `^([0-9]{2}):([0-9]{2}):([0-9]{2})(.[0-9]+)?(z|([+-][0-9]{2}:[0-9]{2}))$`
  55. )
  56. var (
  57. dateTimeFormats = []string{RFC3339Micro, RFC3339Millis, time.RFC3339, time.RFC3339Nano, ISO8601LocalTime}
  58. rxDateTime = regexp.MustCompile(DateTimePattern)
  59. // MarshalFormat sets the time resolution format used for marshaling time (set to milliseconds)
  60. MarshalFormat = RFC3339Millis
  61. )
  62. // ParseDateTime parses a string that represents an ISO8601 time or a unix epoch
  63. func ParseDateTime(data string) (DateTime, error) {
  64. if data == "" {
  65. return NewDateTime(), nil
  66. }
  67. var lastError error
  68. for _, layout := range dateTimeFormats {
  69. dd, err := time.Parse(layout, data)
  70. if err != nil {
  71. lastError = err
  72. continue
  73. }
  74. return DateTime(dd), nil
  75. }
  76. return DateTime{}, lastError
  77. }
  78. // DateTime is a time but it serializes to ISO8601 format with millis
  79. // It knows how to read 3 different variations of a RFC3339 date time.
  80. // Most APIs we encounter want either millisecond or second precision times.
  81. // This just tries to make it worry-free.
  82. //
  83. // swagger:strfmt date-time
  84. type DateTime time.Time
  85. // NewDateTime is a representation of zero value for DateTime type
  86. func NewDateTime() DateTime {
  87. return DateTime(time.Unix(0, 0).UTC())
  88. }
  89. // String converts this time to a string
  90. func (t DateTime) String() string {
  91. return time.Time(t).Format(MarshalFormat)
  92. }
  93. // MarshalText implements the text marshaller interface
  94. func (t DateTime) MarshalText() ([]byte, error) {
  95. return []byte(t.String()), nil
  96. }
  97. // UnmarshalText implements the text unmarshaller interface
  98. func (t *DateTime) UnmarshalText(text []byte) error {
  99. tt, err := ParseDateTime(string(text))
  100. if err != nil {
  101. return err
  102. }
  103. *t = tt
  104. return nil
  105. }
  106. // Scan scans a DateTime value from database driver type.
  107. func (t *DateTime) Scan(raw interface{}) error {
  108. // TODO: case int64: and case float64: ?
  109. switch v := raw.(type) {
  110. case []byte:
  111. return t.UnmarshalText(v)
  112. case string:
  113. return t.UnmarshalText([]byte(v))
  114. case time.Time:
  115. *t = DateTime(v)
  116. case nil:
  117. *t = DateTime{}
  118. default:
  119. return fmt.Errorf("cannot sql.Scan() strfmt.DateTime from: %#v", v)
  120. }
  121. return nil
  122. }
  123. // Value converts DateTime to a primitive value ready to written to a database.
  124. func (t DateTime) Value() (driver.Value, error) {
  125. return driver.Value(t.String()), nil
  126. }
  127. // MarshalJSON returns the DateTime as JSON
  128. func (t DateTime) MarshalJSON() ([]byte, error) {
  129. return json.Marshal(time.Time(t).Format(MarshalFormat))
  130. }
  131. // UnmarshalJSON sets the DateTime from JSON
  132. func (t *DateTime) UnmarshalJSON(data []byte) error {
  133. if string(data) == jsonNull {
  134. return nil
  135. }
  136. var tstr string
  137. if err := json.Unmarshal(data, &tstr); err != nil {
  138. return err
  139. }
  140. tt, err := ParseDateTime(tstr)
  141. if err != nil {
  142. return err
  143. }
  144. *t = tt
  145. return nil
  146. }
  147. func (t DateTime) MarshalBSON() ([]byte, error) {
  148. return bson.Marshal(bson.M{"data": t.String()})
  149. }
  150. func (t *DateTime) UnmarshalBSON(data []byte) error {
  151. var m bson.M
  152. if err := bson.Unmarshal(data, &m); err != nil {
  153. return err
  154. }
  155. if data, ok := m["data"].(string); ok {
  156. rd, err := ParseDateTime(data)
  157. if err != nil {
  158. return err
  159. }
  160. *t = rd
  161. return nil
  162. }
  163. return errors.New("couldn't unmarshal bson bytes value as Date")
  164. }
  165. // DeepCopyInto copies the receiver and writes its value into out.
  166. func (t *DateTime) DeepCopyInto(out *DateTime) {
  167. *out = *t
  168. }
  169. // DeepCopy copies the receiver into a new DateTime.
  170. func (t *DateTime) DeepCopy() *DateTime {
  171. if t == nil {
  172. return nil
  173. }
  174. out := new(DateTime)
  175. t.DeepCopyInto(out)
  176. return out
  177. }
上海开阖软件有限公司 沪ICP备12045867号-1