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-unsubscr...@arrow.apache.org

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


Reply via email to