1. my class Date { ... }
  2. my class DateTime { ... }
  3. my class Duration {... }
  4. my class Instant is Cool does Real {
  5. has Rat $.tai;
  6. # A linear count of seconds since 1970-01-01T00:00:00Z, plus
  7. # Rakudo::Internals.initial-offset. Thus, $.tai matches TAI from 1970
  8. # to the present.
  9. method SET-SELF($!tai) { self } # cannot be private because of operators
  10. method new(*@) { X::Cannot::New.new(class => self).throw }
  11. proto method from-posix(|) {*}
  12. multi method from-posix($posix) {
  13. nqp::create(Instant).SET-SELF(
  14. Rakudo::Internals.tai-from-posix($posix,0).Rat
  15. )
  16. }
  17. multi method from-posix($posix, Bool $prefer-leap-second) {
  18. # $posix is in general not expected to be an integer.
  19. # If $prefer-leap-second is true, 915148800 is interpreted to
  20. # mean 1998-12-31T23:59:60Z rather than 1999-01-01T00:00:00Z.
  21. nqp::create(Instant).SET-SELF(
  22. Rakudo::Internals.tai-from-posix($posix,$prefer-leap-second).Rat
  23. )
  24. }
  25. method to-posix() {
  26. # The inverse of .from-posix, except that the second return
  27. # value is true if *and only if* this Instant is in a leap
  28. # second.
  29. Rakudo::Internals.posix-from-tai($!tai)
  30. }
  31. multi method Str(Instant:D:) {
  32. 'Instant:' ~ $!tai
  33. }
  34. multi method perl(Instant:D:) {
  35. "Instant.from-posix{self.to-posix.perl}";
  36. }
  37. method Bridge(Instant:D:) { $!tai.Bridge }
  38. method Num (Instant:D:) { $!tai.Num }
  39. method Rat (Instant:D:) { $!tai }
  40. method Int (Instant:D:) { $!tai.Int }
  41. method narrow(Instant:D:) { $!tai.narrow }
  42. method Date(Instant:D:) { Date.new(self) }
  43. method DateTime(Instant:D:) { DateTime.new(self) }
  44. method Instant() { self }
  45. # TODO: should be the new .gist, probably
  46. # method Str() {
  47. # 'Instant:' ~ default-formatter
  48. # ::DateTime.new(self), :subseconds
  49. # }
  50. }
  51. multi sub infix:«cmp»(Instant:D $a, Instant:D $b) {
  52. $a.tai <=> $b.tai }
  53. multi sub infix:«<=>»(Instant:D $a, Instant:D $b) {
  54. $a.tai <=> $b.tai
  55. }
  56. multi sub infix:«==»(Instant:D $a, Instant:D $b) {
  57. $a.tai == $b.tai
  58. }
  59. multi sub infix:«!=»(Instant:D $a, Instant:D $b) {
  60. $a.tai != $b.tai
  61. }
  62. multi sub infix:«<»(Instant:D $a, Instant:D $b) {
  63. $a.tai < $b.tai
  64. }
  65. multi sub infix:«>»(Instant:D $a, Instant:D $b) {
  66. $a.tai > $b.tai
  67. }
  68. multi sub infix:«<=»(Instant:D $a, Instant:D $b) {
  69. $a.tai <= $b.tai
  70. }
  71. multi sub infix:«>=»(Instant:D $a, Instant:D $b) {
  72. $a.tai >= $b.tai
  73. }
  74. multi sub infix:<+>(Instant:D $a, Real:D $b) {
  75. nqp::create(Instant).SET-SELF($a.tai + $b.Rat)
  76. }
  77. multi sub infix:<+>(Real:D $a, Instant:D $b) {
  78. nqp::create(Instant).SET-SELF($a.Rat + $b.tai)
  79. }
  80. multi sub infix:<+>(Instant:D $a, Duration:D $b) {
  81. nqp::create(Instant).SET-SELF($a.tai + $b.tai)
  82. }
  83. multi sub infix:<+>(Duration:D $a, Instant:D $b) {
  84. nqp::create(Instant).SET-SELF($a.tai + $b.tai)
  85. }
  86. multi sub infix:<->(Instant:D $a, Instant:D $b) {
  87. Duration.new: $a.tai - $b.tai;
  88. }
  89. multi sub infix:<->(Instant:D $a, Real:D $b) {
  90. nqp::create(Instant).SET-SELF($a.tai - $b.Rat)
  91. }
  92. sub term:<time>() { nqp::p6box_i(nqp::time_i()) }
  93. sub term:<now>() {
  94. # FIXME: During a leap second, the returned value is one
  95. # second greater than it should be.
  96. nqp::create(Instant).SET-SELF(
  97. Rakudo::Internals.tai-from-posix(nqp::time_n,0).Rat
  98. )
  99. }
  100. Rakudo::Internals.REGISTER-DYNAMIC: '$*INIT-INSTANT', {
  101. PROCESS::<$INIT-INSTANT> := nqp::create(Instant).SET-SELF(
  102. Rakudo::Internals.tai-from-posix(Rakudo::Internals.INITTIME,0).Rat
  103. )
  104. }
  105. Rakudo::Internals.REGISTER-DYNAMIC: '$*INITTIME', {
  106. my ($file, $line) = .file, .line with callframe 3;
  107. DEPRECATED('$*INIT-INSTANT', '2017.09.84.gb.02.da.4.d.1.a', '2018.08',
  108. :what<$*INITTIME>, :$file, :$line);
  109. $*INIT-INSTANT
  110. }