You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by GitBox <gi...@apache.org> on 2021/07/15 12:44:43 UTC

[GitHub] [arrow] jorisvandenbossche commented on a change in pull request #10610: ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time)

jorisvandenbossche commented on a change in pull request #10610:
URL: https://github.com/apache/arrow/pull/10610#discussion_r670426594



##########
File path: cpp/src/arrow/compute/kernels/scalar_temporal.cc
##########
@@ -321,6 +341,77 @@ struct Nanosecond {
   }
 };
 
+// ----------------------------------------------------------------------
+// Convert timestamps from arbitrary timezone to UTC
+
+template <typename Duration>
+struct TzLocalize {
+  explicit TzLocalize(const TemporalLocalizationOptions& options)
+      : options(std::move(options)) {}
+
+  template <typename T, typename Arg0>
+  T get_local_time(Arg0 arg) const {
+    return static_cast<T>(
+        arrow_vendored::date::zoned_time<Duration>(
+            options.tz, arrow_vendored::date::local_time<Duration>(Duration{arg}))
+            .get_sys_time()
+            .time_since_epoch()
+            .count());
+  }
+
+  template <typename T, typename Arg0>
+  T get_local_time(Arg0 arg, const arrow_vendored::date::choose choose) const {
+    return static_cast<T>(
+        arrow_vendored::date::zoned_time<Duration>(
+            options.tz, arrow_vendored::date::local_time<Duration>(Duration{arg}), choose)
+            .get_sys_time()
+            .time_since_epoch()
+            .count());
+  }
+
+  template <typename T, typename Arg0>
+  T Call(KernelContext*, Arg0 arg, Status* st) const {
+    try {
+      return get_local_time<T, Arg0>(arg);
+    } catch (const arrow_vendored::date::nonexistent_local_time& e) {
+      switch (options.nonexistent) {
+        case TemporalLocalizationOptions::Nonexistent::RAISE_NONEXISTENT: {
+          *st = Status::Invalid("Nonexistent: ", e.what());
+          return arg;
+        }
+        case TemporalLocalizationOptions::Nonexistent::SHIFT_BACKWARD: {
+          return get_local_time<T, Arg0>(arg, arrow_vendored::date::choose::earliest);
+        }
+        case TemporalLocalizationOptions::Nonexistent::SHIFT_FORWARD: {
+          return get_local_time<T, Arg0>(arg, arrow_vendored::date::choose::latest);
+        }
+        case TemporalLocalizationOptions::Nonexistent::IGNORE_NONEXISTENT: {
+          return static_cast<T>(NULL);
+        }
+      }
+    } catch (const arrow_vendored::date::ambiguous_local_time& e) {
+      switch (options.ambiguous) {
+        case TemporalLocalizationOptions::Ambiguous::RAISE_AMBIGUOUS: {
+          *st = Status::Invalid("Ambiguous: ", e.what());
+          return arg;
+        }
+        case TemporalLocalizationOptions::Ambiguous::FIRST: {
+          return get_local_time<T, Arg0>(arg, arrow_vendored::date::choose::earliest);
+        }
+        case TemporalLocalizationOptions::Ambiguous::LAST: {
+          return get_local_time<T, Arg0>(arg, arrow_vendored::date::choose::latest);

Review comment:
       For `nonexistent`, we use "shift_backward" and "shift_forward" for earliest/latest, and here we use "first" and "last" for the `ambiguous` keyword. Shall we make this consistent?  (and could then also use the terminology of date.h)




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org