time.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2011 Google Inc. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package uuid
  5. import (
  6. "encoding/binary"
  7. "time"
  8. )
  9. // A Time represents a time as the number of 100's of nanoseconds since 15 Oct
  10. // 1582.
  11. type Time int64
  12. const (
  13. lillian = 2299160 // Julian day of 15 Oct 1582
  14. unix = 2440587 // Julian day of 1 Jan 1970
  15. epoch = unix - lillian // Days between epochs
  16. g1582 = epoch * 86400 // seconds between epochs
  17. g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
  18. )
  19. var (
  20. lasttime uint64 // last time we returned
  21. clock_seq uint16 // clock sequence for this run
  22. timeNow = time.Now // for testing
  23. )
  24. // UnixTime converts t the number of seconds and nanoseconds using the Unix
  25. // epoch of 1 Jan 1970.
  26. func (t Time) UnixTime() (sec, nsec int64) {
  27. sec = int64(t - g1582ns100)
  28. nsec = (sec % 10000000) * 100
  29. sec /= 10000000
  30. return sec, nsec
  31. }
  32. // GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
  33. // adjusts the clock sequence as needed. An error is returned if the current
  34. // time cannot be determined.
  35. func GetTime() (Time, error) {
  36. t := timeNow()
  37. // If we don't have a clock sequence already, set one.
  38. if clock_seq == 0 {
  39. SetClockSequence(-1)
  40. }
  41. now := uint64(t.UnixNano()/100) + g1582ns100
  42. // If time has gone backwards with this clock sequence then we
  43. // increment the clock sequence
  44. if now <= lasttime {
  45. clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000
  46. }
  47. lasttime = now
  48. return Time(now), nil
  49. }
  50. // ClockSequence returns the current clock sequence, generating one if not
  51. // already set. The clock sequence is only used for Version 1 UUIDs.
  52. //
  53. // The uuid package does not use global static storage for the clock sequence or
  54. // the last time a UUID was generated. Unless SetClockSequence a new random
  55. // clock sequence is generated the first time a clock sequence is requested by
  56. // ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated
  57. // for
  58. func ClockSequence() int {
  59. if clock_seq == 0 {
  60. SetClockSequence(-1)
  61. }
  62. return int(clock_seq & 0x3fff)
  63. }
  64. // SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to
  65. // -1 causes a new sequence to be generated.
  66. func SetClockSequence(seq int) {
  67. if seq == -1 {
  68. var b [2]byte
  69. randomBits(b[:]) // clock sequence
  70. seq = int(b[0])<<8 | int(b[1])
  71. }
  72. old_seq := clock_seq
  73. clock_seq = uint16(seq&0x3fff) | 0x8000 // Set our variant
  74. if old_seq != clock_seq {
  75. lasttime = 0
  76. }
  77. }
  78. // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
  79. // uuid. It returns false if uuid is not valid. The time is only well defined
  80. // for version 1 and 2 UUIDs.
  81. func (uuid UUID) Time() (Time, bool) {
  82. if len(uuid) != 16 {
  83. return 0, false
  84. }
  85. time := int64(binary.BigEndian.Uint32(uuid[0:4]))
  86. time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
  87. time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
  88. return Time(time), true
  89. }
  90. // ClockSequence returns the clock sequence encoded in uuid. It returns false
  91. // if uuid is not valid. The clock sequence is only well defined for version 1
  92. // and 2 UUIDs.
  93. func (uuid UUID) ClockSequence() (int, bool) {
  94. if len(uuid) != 16 {
  95. return 0, false
  96. }
  97. return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true
  98. }