datetime64.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #pragma once
  2. #include <util/datetime/base.h>
  3. #include "datetime.h"
  4. namespace NYql::DateTime {
  5. struct TTM64Storage {
  6. i32 Year : 19;
  7. ui32 DayOfYear : 9;
  8. ui32 WeekOfYear : 6;
  9. ui32 WeekOfYearIso8601 : 6;
  10. ui32 DayOfWeek : 3;
  11. ui32 Month : 4;
  12. ui32 Day : 5;
  13. ui32 Hour : 5;
  14. ui32 Minute : 6;
  15. ui32 Second : 6;
  16. ui32 Microsecond : 20;
  17. ui32 TimezoneId : 16;
  18. TTM64Storage() {
  19. Zero(*this);
  20. }
  21. static bool IsUniversal(ui16 tzId) {
  22. return tzId == 0;
  23. }
  24. void MakeDefault() {
  25. Year = 1970;
  26. Month = 1;
  27. Day = 1;
  28. Hour = 0;
  29. Minute = 0;
  30. Second = 0;
  31. Microsecond = 0;
  32. TimezoneId = 0;
  33. }
  34. void From(const TTMStorage& narrow) {
  35. Year = narrow.Year;
  36. DayOfYear = narrow.DayOfYear;
  37. WeekOfYear = narrow.WeekOfYear;
  38. WeekOfYearIso8601 = narrow.WeekOfYearIso8601;
  39. DayOfWeek = narrow.DayOfWeek;
  40. Month = narrow.Month;
  41. Day = narrow.Day;
  42. Hour = narrow.Hour;
  43. Minute = narrow.Minute;
  44. Second = narrow.Second;
  45. Microsecond = narrow.Microsecond;
  46. TimezoneId = narrow.TimezoneId;
  47. }
  48. void FromDate32(const NUdf::IDateBuilder& builder, i32 value, ui16 tzId = 0) {
  49. i32 year;
  50. ui32 month, day, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek;
  51. if (!builder.SplitTzDate32(value, year, month, day, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek, tzId)) {
  52. ythrow yexception() << "Error in SplitTzDate32 tzId " << tzId << " value " << value;
  53. }
  54. TimezoneId = tzId;
  55. Year = year;
  56. Month = month;
  57. Day = day;
  58. DayOfYear = dayOfYear;
  59. WeekOfYear = weekOfYear;
  60. WeekOfYearIso8601 = weekOfYearIso8601;
  61. DayOfWeek = dayOfWeek;
  62. }
  63. void FromDatetime64(const NUdf::IDateBuilder& builder, i64 value, ui16 tzId = 0) {
  64. i32 year;
  65. ui32 month, day, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek;
  66. ui32 hour, minute, second;
  67. if (!builder.SplitTzDatetime64(
  68. value, year, month, day, hour, minute, second,
  69. dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek, tzId))
  70. {
  71. ythrow yexception() << "Error in SplitTzDatetime64 tzId " << tzId << " value " << value;
  72. }
  73. TimezoneId = tzId;
  74. Year = year;
  75. Month = month;
  76. Day = day;
  77. Hour = hour;
  78. Minute = minute;
  79. Second = second;
  80. DayOfYear = dayOfYear;
  81. WeekOfYear = weekOfYear;
  82. WeekOfYearIso8601 = weekOfYearIso8601;
  83. DayOfWeek = dayOfWeek;
  84. }
  85. void FromTimestamp64(const NUdf::IDateBuilder& builder, i64 value, ui16 tzId = 0) {
  86. i64 datetime = value / 1000000ll;
  87. if (value % 1000000ll < 0) {
  88. datetime -= 1;
  89. }
  90. FromDatetime64(builder, datetime, tzId);
  91. Microsecond = value - datetime * 1000000ll;
  92. }
  93. i32 ToDate32(const NUdf::IDateBuilder& builder, bool local) const {
  94. if (!IsUniversal(TimezoneId)) {
  95. i64 datetime;
  96. ui32 hour = local ? 0 : Hour;
  97. ui32 minute = local ? 0 : Minute;
  98. ui32 second = local ? 0 : Second;
  99. if (!builder.MakeTzDatetime64(Year, Month, Day, hour, minute, second, datetime, TimezoneId)) {
  100. ythrow yexception() << "Error in MakeTzDatetime64 tzId "
  101. << TimezoneId << " " << Year << "-" << Month << "-" << Day
  102. << "T" << hour << ":" << minute << ":" << second;
  103. }
  104. return datetime / 86400u;
  105. } else {
  106. i32 date;
  107. if (!builder.MakeTzDate32(Year, Month, Day, date, TimezoneId)) {
  108. ythrow yexception() << "Error in MakeTzDate32 tzId "
  109. << TimezoneId << " " << Year << "-" << Month << "-" << Day;
  110. }
  111. return date;
  112. }
  113. }
  114. i64 ToDatetime64(const NUdf::IDateBuilder& builder) const {
  115. i64 datetime;
  116. if (!builder.MakeTzDatetime64(Year, Month, Day, Hour, Minute, Second, datetime, TimezoneId)) {
  117. ythrow yexception() << "Error in MakeTzDatetime64 tzId " << TimezoneId
  118. << " " << Year << "-" << Month << "-" << Day << "T" << Hour << ":" << Minute << ":" << Second;
  119. }
  120. return datetime;
  121. }
  122. i64 ToTimestamp64(const NUdf::IDateBuilder& builder) const {
  123. return ToDatetime64(builder) * 1000000ll + Microsecond;
  124. }
  125. inline bool Validate(const NUdf::IDateBuilder& builder) {
  126. i64 datetime;
  127. if (!builder.MakeTzDatetime64(Year, Month, Day, Hour, Minute, Second, datetime, TimezoneId)) {
  128. return false;
  129. }
  130. i32 year;
  131. ui32 month, day, hour, minute, second, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek;
  132. if (!builder.SplitTzDatetime64(datetime, year, month, day, hour, minute, second, dayOfYear, weekOfYear, weekOfYearIso8601, dayOfWeek, TimezoneId)) {
  133. ythrow yexception() << "Error in SplitTzDatetime64";
  134. }
  135. DayOfYear = dayOfYear;
  136. WeekOfYear = weekOfYear;
  137. WeekOfYearIso8601 = weekOfYearIso8601;
  138. DayOfWeek = dayOfWeek;
  139. return true;
  140. }
  141. inline void FromTimeOfDay(ui64 value) {
  142. Hour = value / 3600000000ull;
  143. value -= Hour * 3600000000ull;
  144. Minute = value / 60000000ull;
  145. value -= Minute * 60000000ull;
  146. Second = value / 1000000ull;
  147. Microsecond = value - Second * 1000000ull;
  148. }
  149. inline ui64 ToTimeOfDay() const {
  150. return ((Hour * 60ull + Minute) * 60ull + Second) * 1000000ull + Microsecond;
  151. }
  152. const TString ToString() const {
  153. const auto& tzName = NUdf::GetTimezones()[TimezoneId];
  154. return Sprintf("%8d-%02d-%02dT%02d:%02d:%02d.%06d,%.*s",
  155. Year, Month, Day, Hour, Minute, Second, Microsecond,
  156. static_cast<int>(tzName.size()), tzName.data());
  157. }
  158. };
  159. }