ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time) - #10610

Closed
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033
Closed

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time)#10610
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033

Conversation

@rok

@rokrok commented Jun 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13033.

@github-actions

Copy link
Copy Markdown

@jorisvandenbosschejorisvandenbossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given all the discussion on the JIRA issue, can you a bit more clearly state what exactly you implemented and what part it covers?
For example, the current kernel returns int64 and not timestamp with timezone?

It also seems that the implementation is converting system time (UTC epoch) to local (naive) time, and not the other way around as the docstring says.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
Comment threaddocs/source/cpp/compute.rst Outdated
@rok
rokforce-pushed the ARROW-13033 branch 2 times, most recently from 3b14063 to 7fa50a6CompareJuly 2, 2021 00:37
@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche :).
I've gone through your feedback and done some of the boilerplate except for the correct output timestamp type. I'll try to do it over the weekend.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

I think there is no consensus on this yet. tz_convert, tz_localize were mentioned. I'd add tz_normalize. Any other?

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

In case we start with "naive" a timestamp we don't know the source and target timezone so both need to be specified. Or am I missing something here?

@jorisvandenbossche

Copy link
Copy Markdown
Member

What's the difference between both timezones? In my mind this is the same time zone? If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

I was thinking only of the metadata change not "materialization" of a target timezone. Having another kernel to only change metadata seems redundant.

@jorisvandenbossche

Copy link
Copy Markdown
Member

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

@jorisvandenbossche

Copy link
Copy Markdown
Member

(if we keep both source and destination timezone in the "localize" kernel, I think at least the destination timezone, if not specified, should default to be the same as the source timezone, and not "UTC", so that a user doesn't have to specify the timezone they want twice, like localize(timestamp, source_timezone="Europe/Brussels", destination_timezone="Europe/Brussels") to end up with a timestamp(unit, tz="Europe/Brussels) type column)

@jorisvandenbossche

Copy link
Copy Markdown
Member

I opened https://issues.apache.org/jira/browse/ARROW-13247 for the discussion whether we want a separate "change timezone" kernel

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

I suppose these are two different operations indeed. I've changed this to only do "localization" now.

I like force_tz as it indicates the operation is a bit "dangerous". Candidates are then:

  • force_tz
  • tz_localize
  • tz_normalize

@adamhooper

Copy link
Copy Markdown
Contributor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

It's nice that it's idiomatic if a bit verbose :)

Let's add it to the list. If we don't get to consensus here we can always call a vote on the ML.

  • force_tz
  • tz_localize
  • tz_normalize
  • local_datetime_to_zoned_datetime

@westonpace

Copy link
Copy Markdown
Member

I like all except tz_normalize. "normalize" just has too many meanings for me already.

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

And from testing, you will still need to handle the errors raised by date.h:

In [21]: arr = pa.array([pd.Timestamp("2021-03-28 02:30:00")], type=pa.timestamp("ns"))
In [22]: pc.localize(arr, options=pc.TemporalLocalizationOptions("Europe/Brussels"))
terminate called after throwing an instance of 'arrow_vendored::date::nonexistent_local_time'
what(): 2021-03-28 02:30:00.000000000 is in a gap between
2021-03-28 02:00:00 CET and
2021-03-28 03:00:00 CEST which are both equivalent to
2021-03-28 01:00:00 UTC
Aborted (core dumped)

@rok

rok commented Jul 6, 2021

Copy link
Copy Markdown
MemberAuthor

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

Thanks @jorisvandenbossche! The new option initialization was indeed problematic.

@rok
rokforce-pushed the ARROW-13033 branch 8 times, most recently from 7c1ebb5 to c5a62a9CompareJuly 7, 2021 12:16
@pitrou

Copy link
Copy Markdown
Member

I'm going to suggest assume_timezone.

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

What would be a good way to reach consensus here? A doodle poll to ML to see what people find most intuitive?

@pitrou

Copy link
Copy Markdown
Member

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You may still ask for opinions on the ML, but I would personally go with assume_timezone. Users will have to read the documentation in any case.

@rok

rok commented Aug 26, 2021

Copy link
Copy Markdown
MemberAuthor

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You mean timestamps and timezones in general are weird (because the underlying problem is counter intuitive)? If not we should really make this as simple as the underlying complexity is.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 551cb2c to 76ad88fCompareSeptember 2, 2021 11:03
@rok
rok requested a review from pitrouSeptember 2, 2021 14:56
@rok

rok commented Sep 2, 2021

Copy link
Copy Markdown
MemberAuthor

@pitrou I've changed this to assume_timezone (AssumeTimezone, AssumeTimezoneOptions).
Discussion on Zulip seems to be in favor of assume_timestamp.

Would still be good to hear @jorisvandenbossche@adamhooper@westonpace

@adamhooper

Copy link
Copy Markdown
Contributor

@rok Thanks for asking! I prefer assume_timezone, too.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be here. Is it deliberate or just a leftover?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Probably a bad rebase.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what this is for. Presumably this should be unreachable?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just to satisfy the compiler.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the status but kept the return 0 to keep he compiler happy. Please check.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 008bf23 to 87ddd31CompareSeptember 6, 2021 17:12
@rok
rok requested a review from pitrouSeptember 6, 2021 19:04
@rok

rok commented Sep 6, 2021

Copy link
Copy Markdown
MemberAuthor

CI fail seems unrelated.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
@pitrou

Copy link
Copy Markdown
Member

Ok, I've pushed some minor changes and will merge once CI is green. Thanks a lot for this @rok !

@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

Let me rebase that.

@pitrou

Copy link
Copy Markdown
Member

@rok I'm on it already.

Work.
Removing destination_timezone.
fix initialization of timezone + add python bindings
Renaming localize to tz_localize.
Adding ambiguous and nonexistent handling.
Removing R wrapper.
Reintroducing R wrapper.
Issue with date.h building on rtools4.0.
Review feedback.
tz_localize -> assume_timezone
Review feedback.
Changes to nonexistent handling.
More changes to nonexistent handling.
* Documentation changes
* Simplify kernel generation
@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
…(preserving clock-time)
This is to resolve [ARROW-13033](https://issues.apache.org/jira/browse/ARROW-13033).
Closesapache#10610 from rok/ARROW-13033
Authored-by: Rok <rok@mihevc.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rok@jorisvandenbossche@adamhooper@westonpace@pitrou
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time) - #10610

Closed
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033
Closed

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time)#10610
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033

Conversation

@rok

@rokrok commented Jun 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13033.

@github-actions

Copy link
Copy Markdown

@jorisvandenbosschejorisvandenbossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given all the discussion on the JIRA issue, can you a bit more clearly state what exactly you implemented and what part it covers?
For example, the current kernel returns int64 and not timestamp with timezone?

It also seems that the implementation is converting system time (UTC epoch) to local (naive) time, and not the other way around as the docstring says.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
Comment threaddocs/source/cpp/compute.rst Outdated
@rok
rokforce-pushed the ARROW-13033 branch 2 times, most recently from 3b14063 to 7fa50a6CompareJuly 2, 2021 00:37
@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche :).
I've gone through your feedback and done some of the boilerplate except for the correct output timestamp type. I'll try to do it over the weekend.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

I think there is no consensus on this yet. tz_convert, tz_localize were mentioned. I'd add tz_normalize. Any other?

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

In case we start with "naive" a timestamp we don't know the source and target timezone so both need to be specified. Or am I missing something here?

@jorisvandenbossche

Copy link
Copy Markdown
Member

What's the difference between both timezones? In my mind this is the same time zone? If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

I was thinking only of the metadata change not "materialization" of a target timezone. Having another kernel to only change metadata seems redundant.

@jorisvandenbossche

Copy link
Copy Markdown
Member

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

@jorisvandenbossche

Copy link
Copy Markdown
Member

(if we keep both source and destination timezone in the "localize" kernel, I think at least the destination timezone, if not specified, should default to be the same as the source timezone, and not "UTC", so that a user doesn't have to specify the timezone they want twice, like localize(timestamp, source_timezone="Europe/Brussels", destination_timezone="Europe/Brussels") to end up with a timestamp(unit, tz="Europe/Brussels) type column)

@jorisvandenbossche

Copy link
Copy Markdown
Member

I opened https://issues.apache.org/jira/browse/ARROW-13247 for the discussion whether we want a separate "change timezone" kernel

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

I suppose these are two different operations indeed. I've changed this to only do "localization" now.

I like force_tz as it indicates the operation is a bit "dangerous". Candidates are then:

  • force_tz
  • tz_localize
  • tz_normalize

@adamhooper

Copy link
Copy Markdown
Contributor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

It's nice that it's idiomatic if a bit verbose :)

Let's add it to the list. If we don't get to consensus here we can always call a vote on the ML.

  • force_tz
  • tz_localize
  • tz_normalize
  • local_datetime_to_zoned_datetime

@westonpace

Copy link
Copy Markdown
Member

I like all except tz_normalize. "normalize" just has too many meanings for me already.

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

And from testing, you will still need to handle the errors raised by date.h:

In [21]: arr = pa.array([pd.Timestamp("2021-03-28 02:30:00")], type=pa.timestamp("ns"))
In [22]: pc.localize(arr, options=pc.TemporalLocalizationOptions("Europe/Brussels"))
terminate called after throwing an instance of 'arrow_vendored::date::nonexistent_local_time'
what(): 2021-03-28 02:30:00.000000000 is in a gap between
2021-03-28 02:00:00 CET and
2021-03-28 03:00:00 CEST which are both equivalent to
2021-03-28 01:00:00 UTC
Aborted (core dumped)

@rok

rok commented Jul 6, 2021

Copy link
Copy Markdown
MemberAuthor

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

Thanks @jorisvandenbossche! The new option initialization was indeed problematic.

@rok
rokforce-pushed the ARROW-13033 branch 8 times, most recently from 7c1ebb5 to c5a62a9CompareJuly 7, 2021 12:16
@pitrou

Copy link
Copy Markdown
Member

I'm going to suggest assume_timezone.

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

What would be a good way to reach consensus here? A doodle poll to ML to see what people find most intuitive?

@pitrou

Copy link
Copy Markdown
Member

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You may still ask for opinions on the ML, but I would personally go with assume_timezone. Users will have to read the documentation in any case.

@rok

rok commented Aug 26, 2021

Copy link
Copy Markdown
MemberAuthor

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You mean timestamps and timezones in general are weird (because the underlying problem is counter intuitive)? If not we should really make this as simple as the underlying complexity is.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 551cb2c to 76ad88fCompareSeptember 2, 2021 11:03
@rok
rok requested a review from pitrouSeptember 2, 2021 14:56
@rok

rok commented Sep 2, 2021

Copy link
Copy Markdown
MemberAuthor

@pitrou I've changed this to assume_timezone (AssumeTimezone, AssumeTimezoneOptions).
Discussion on Zulip seems to be in favor of assume_timestamp.

Would still be good to hear @jorisvandenbossche@adamhooper@westonpace

@adamhooper

Copy link
Copy Markdown
Contributor

@rok Thanks for asking! I prefer assume_timezone, too.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be here. Is it deliberate or just a leftover?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Probably a bad rebase.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what this is for. Presumably this should be unreachable?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just to satisfy the compiler.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the status but kept the return 0 to keep he compiler happy. Please check.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 008bf23 to 87ddd31CompareSeptember 6, 2021 17:12
@rok
rok requested a review from pitrouSeptember 6, 2021 19:04
@rok

rok commented Sep 6, 2021

Copy link
Copy Markdown
MemberAuthor

CI fail seems unrelated.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
@pitrou

Copy link
Copy Markdown
Member

Ok, I've pushed some minor changes and will merge once CI is green. Thanks a lot for this @rok !

@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

Let me rebase that.

@pitrou

Copy link
Copy Markdown
Member

@rok I'm on it already.

Work.
Removing destination_timezone.
fix initialization of timezone + add python bindings
Renaming localize to tz_localize.
Adding ambiguous and nonexistent handling.
Removing R wrapper.
Reintroducing R wrapper.
Issue with date.h building on rtools4.0.
Review feedback.
tz_localize -> assume_timezone
Review feedback.
Changes to nonexistent handling.
More changes to nonexistent handling.
* Documentation changes
* Simplify kernel generation
@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
…(preserving clock-time)
This is to resolve [ARROW-13033](https://issues.apache.org/jira/browse/ARROW-13033).
Closesapache#10610 from rok/ARROW-13033
Authored-by: Rok <rok@mihevc.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rok@jorisvandenbossche@adamhooper@westonpace@pitrou
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time) - #10610

Closed
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033
Closed

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time)#10610
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033

Conversation

@rok

@rokrok commented Jun 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13033.

@github-actions

Copy link
Copy Markdown

@jorisvandenbosschejorisvandenbossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given all the discussion on the JIRA issue, can you a bit more clearly state what exactly you implemented and what part it covers?
For example, the current kernel returns int64 and not timestamp with timezone?

It also seems that the implementation is converting system time (UTC epoch) to local (naive) time, and not the other way around as the docstring says.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
Comment threaddocs/source/cpp/compute.rst Outdated
@rok
rokforce-pushed the ARROW-13033 branch 2 times, most recently from 3b14063 to 7fa50a6CompareJuly 2, 2021 00:37
@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche :).
I've gone through your feedback and done some of the boilerplate except for the correct output timestamp type. I'll try to do it over the weekend.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

I think there is no consensus on this yet. tz_convert, tz_localize were mentioned. I'd add tz_normalize. Any other?

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

In case we start with "naive" a timestamp we don't know the source and target timezone so both need to be specified. Or am I missing something here?

@jorisvandenbossche

Copy link
Copy Markdown
Member

What's the difference between both timezones? In my mind this is the same time zone? If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

I was thinking only of the metadata change not "materialization" of a target timezone. Having another kernel to only change metadata seems redundant.

@jorisvandenbossche

Copy link
Copy Markdown
Member

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

@jorisvandenbossche

Copy link
Copy Markdown
Member

(if we keep both source and destination timezone in the "localize" kernel, I think at least the destination timezone, if not specified, should default to be the same as the source timezone, and not "UTC", so that a user doesn't have to specify the timezone they want twice, like localize(timestamp, source_timezone="Europe/Brussels", destination_timezone="Europe/Brussels") to end up with a timestamp(unit, tz="Europe/Brussels) type column)

@jorisvandenbossche

Copy link
Copy Markdown
Member

I opened https://issues.apache.org/jira/browse/ARROW-13247 for the discussion whether we want a separate "change timezone" kernel

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

I suppose these are two different operations indeed. I've changed this to only do "localization" now.

I like force_tz as it indicates the operation is a bit "dangerous". Candidates are then:

  • force_tz
  • tz_localize
  • tz_normalize

@adamhooper

Copy link
Copy Markdown
Contributor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

It's nice that it's idiomatic if a bit verbose :)

Let's add it to the list. If we don't get to consensus here we can always call a vote on the ML.

  • force_tz
  • tz_localize
  • tz_normalize
  • local_datetime_to_zoned_datetime

@westonpace

Copy link
Copy Markdown
Member

I like all except tz_normalize. "normalize" just has too many meanings for me already.

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

And from testing, you will still need to handle the errors raised by date.h:

In [21]: arr = pa.array([pd.Timestamp("2021-03-28 02:30:00")], type=pa.timestamp("ns"))
In [22]: pc.localize(arr, options=pc.TemporalLocalizationOptions("Europe/Brussels"))
terminate called after throwing an instance of 'arrow_vendored::date::nonexistent_local_time'
what(): 2021-03-28 02:30:00.000000000 is in a gap between
2021-03-28 02:00:00 CET and
2021-03-28 03:00:00 CEST which are both equivalent to
2021-03-28 01:00:00 UTC
Aborted (core dumped)

@rok

rok commented Jul 6, 2021

Copy link
Copy Markdown
MemberAuthor

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

Thanks @jorisvandenbossche! The new option initialization was indeed problematic.

@rok
rokforce-pushed the ARROW-13033 branch 8 times, most recently from 7c1ebb5 to c5a62a9CompareJuly 7, 2021 12:16
@pitrou

Copy link
Copy Markdown
Member

I'm going to suggest assume_timezone.

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

What would be a good way to reach consensus here? A doodle poll to ML to see what people find most intuitive?

@pitrou

Copy link
Copy Markdown
Member

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You may still ask for opinions on the ML, but I would personally go with assume_timezone. Users will have to read the documentation in any case.

@rok

rok commented Aug 26, 2021

Copy link
Copy Markdown
MemberAuthor

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You mean timestamps and timezones in general are weird (because the underlying problem is counter intuitive)? If not we should really make this as simple as the underlying complexity is.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 551cb2c to 76ad88fCompareSeptember 2, 2021 11:03
@rok
rok requested a review from pitrouSeptember 2, 2021 14:56
@rok

rok commented Sep 2, 2021

Copy link
Copy Markdown
MemberAuthor

@pitrou I've changed this to assume_timezone (AssumeTimezone, AssumeTimezoneOptions).
Discussion on Zulip seems to be in favor of assume_timestamp.

Would still be good to hear @jorisvandenbossche@adamhooper@westonpace

@adamhooper

Copy link
Copy Markdown
Contributor

@rok Thanks for asking! I prefer assume_timezone, too.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be here. Is it deliberate or just a leftover?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Probably a bad rebase.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what this is for. Presumably this should be unreachable?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just to satisfy the compiler.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the status but kept the return 0 to keep he compiler happy. Please check.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 008bf23 to 87ddd31CompareSeptember 6, 2021 17:12
@rok
rok requested a review from pitrouSeptember 6, 2021 19:04
@rok

rok commented Sep 6, 2021

Copy link
Copy Markdown
MemberAuthor

CI fail seems unrelated.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
@pitrou

Copy link
Copy Markdown
Member

Ok, I've pushed some minor changes and will merge once CI is green. Thanks a lot for this @rok !

@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

Let me rebase that.

@pitrou

Copy link
Copy Markdown
Member

@rok I'm on it already.

Work.
Removing destination_timezone.
fix initialization of timezone + add python bindings
Renaming localize to tz_localize.
Adding ambiguous and nonexistent handling.
Removing R wrapper.
Reintroducing R wrapper.
Issue with date.h building on rtools4.0.
Review feedback.
tz_localize -> assume_timezone
Review feedback.
Changes to nonexistent handling.
More changes to nonexistent handling.
* Documentation changes
* Simplify kernel generation
@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
…(preserving clock-time)
This is to resolve [ARROW-13033](https://issues.apache.org/jira/browse/ARROW-13033).
Closesapache#10610 from rok/ARROW-13033
Authored-by: Rok <rok@mihevc.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rok@jorisvandenbossche@adamhooper@westonpace@pitrou
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time) - #10610

Closed
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033
Closed

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time)#10610
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033

Conversation

@rok

@rokrok commented Jun 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13033.

@github-actions

Copy link
Copy Markdown

@jorisvandenbosschejorisvandenbossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given all the discussion on the JIRA issue, can you a bit more clearly state what exactly you implemented and what part it covers?
For example, the current kernel returns int64 and not timestamp with timezone?

It also seems that the implementation is converting system time (UTC epoch) to local (naive) time, and not the other way around as the docstring says.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
Comment threaddocs/source/cpp/compute.rst Outdated
@rok
rokforce-pushed the ARROW-13033 branch 2 times, most recently from 3b14063 to 7fa50a6CompareJuly 2, 2021 00:37
@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche :).
I've gone through your feedback and done some of the boilerplate except for the correct output timestamp type. I'll try to do it over the weekend.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

I think there is no consensus on this yet. tz_convert, tz_localize were mentioned. I'd add tz_normalize. Any other?

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

In case we start with "naive" a timestamp we don't know the source and target timezone so both need to be specified. Or am I missing something here?

@jorisvandenbossche

Copy link
Copy Markdown
Member

What's the difference between both timezones? In my mind this is the same time zone? If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

I was thinking only of the metadata change not "materialization" of a target timezone. Having another kernel to only change metadata seems redundant.

@jorisvandenbossche

Copy link
Copy Markdown
Member

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

@jorisvandenbossche

Copy link
Copy Markdown
Member

(if we keep both source and destination timezone in the "localize" kernel, I think at least the destination timezone, if not specified, should default to be the same as the source timezone, and not "UTC", so that a user doesn't have to specify the timezone they want twice, like localize(timestamp, source_timezone="Europe/Brussels", destination_timezone="Europe/Brussels") to end up with a timestamp(unit, tz="Europe/Brussels) type column)

@jorisvandenbossche

Copy link
Copy Markdown
Member

I opened https://issues.apache.org/jira/browse/ARROW-13247 for the discussion whether we want a separate "change timezone" kernel

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

I suppose these are two different operations indeed. I've changed this to only do "localization" now.

I like force_tz as it indicates the operation is a bit "dangerous". Candidates are then:

  • force_tz
  • tz_localize
  • tz_normalize

@adamhooper

Copy link
Copy Markdown
Contributor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

It's nice that it's idiomatic if a bit verbose :)

Let's add it to the list. If we don't get to consensus here we can always call a vote on the ML.

  • force_tz
  • tz_localize
  • tz_normalize
  • local_datetime_to_zoned_datetime

@westonpace

Copy link
Copy Markdown
Member

I like all except tz_normalize. "normalize" just has too many meanings for me already.

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

And from testing, you will still need to handle the errors raised by date.h:

In [21]: arr = pa.array([pd.Timestamp("2021-03-28 02:30:00")], type=pa.timestamp("ns"))
In [22]: pc.localize(arr, options=pc.TemporalLocalizationOptions("Europe/Brussels"))
terminate called after throwing an instance of 'arrow_vendored::date::nonexistent_local_time'
what(): 2021-03-28 02:30:00.000000000 is in a gap between
2021-03-28 02:00:00 CET and
2021-03-28 03:00:00 CEST which are both equivalent to
2021-03-28 01:00:00 UTC
Aborted (core dumped)

@rok

rok commented Jul 6, 2021

Copy link
Copy Markdown
MemberAuthor

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

Thanks @jorisvandenbossche! The new option initialization was indeed problematic.

@rok
rokforce-pushed the ARROW-13033 branch 8 times, most recently from 7c1ebb5 to c5a62a9CompareJuly 7, 2021 12:16
@pitrou

Copy link
Copy Markdown
Member

I'm going to suggest assume_timezone.

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

What would be a good way to reach consensus here? A doodle poll to ML to see what people find most intuitive?

@pitrou

Copy link
Copy Markdown
Member

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You may still ask for opinions on the ML, but I would personally go with assume_timezone. Users will have to read the documentation in any case.

@rok

rok commented Aug 26, 2021

Copy link
Copy Markdown
MemberAuthor

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You mean timestamps and timezones in general are weird (because the underlying problem is counter intuitive)? If not we should really make this as simple as the underlying complexity is.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 551cb2c to 76ad88fCompareSeptember 2, 2021 11:03
@rok
rok requested a review from pitrouSeptember 2, 2021 14:56
@rok

rok commented Sep 2, 2021

Copy link
Copy Markdown
MemberAuthor

@pitrou I've changed this to assume_timezone (AssumeTimezone, AssumeTimezoneOptions).
Discussion on Zulip seems to be in favor of assume_timestamp.

Would still be good to hear @jorisvandenbossche@adamhooper@westonpace

@adamhooper

Copy link
Copy Markdown
Contributor

@rok Thanks for asking! I prefer assume_timezone, too.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be here. Is it deliberate or just a leftover?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Probably a bad rebase.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what this is for. Presumably this should be unreachable?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just to satisfy the compiler.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the status but kept the return 0 to keep he compiler happy. Please check.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 008bf23 to 87ddd31CompareSeptember 6, 2021 17:12
@rok
rok requested a review from pitrouSeptember 6, 2021 19:04
@rok

rok commented Sep 6, 2021

Copy link
Copy Markdown
MemberAuthor

CI fail seems unrelated.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
@pitrou

Copy link
Copy Markdown
Member

Ok, I've pushed some minor changes and will merge once CI is green. Thanks a lot for this @rok !

@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

Let me rebase that.

@pitrou

Copy link
Copy Markdown
Member

@rok I'm on it already.

Work.
Removing destination_timezone.
fix initialization of timezone + add python bindings
Renaming localize to tz_localize.
Adding ambiguous and nonexistent handling.
Removing R wrapper.
Reintroducing R wrapper.
Issue with date.h building on rtools4.0.
Review feedback.
tz_localize -> assume_timezone
Review feedback.
Changes to nonexistent handling.
More changes to nonexistent handling.
* Documentation changes
* Simplify kernel generation
@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
…(preserving clock-time)
This is to resolve [ARROW-13033](https://issues.apache.org/jira/browse/ARROW-13033).
Closesapache#10610 from rok/ARROW-13033
Authored-by: Rok <rok@mihevc.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rok@jorisvandenbossche@adamhooper@westonpace@pitrou
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time) - #10610

Closed
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033
Closed

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time)#10610
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033

Conversation

@rok

@rokrok commented Jun 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13033.

@github-actions

Copy link
Copy Markdown

@jorisvandenbosschejorisvandenbossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given all the discussion on the JIRA issue, can you a bit more clearly state what exactly you implemented and what part it covers?
For example, the current kernel returns int64 and not timestamp with timezone?

It also seems that the implementation is converting system time (UTC epoch) to local (naive) time, and not the other way around as the docstring says.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
Comment threaddocs/source/cpp/compute.rst Outdated
@rok
rokforce-pushed the ARROW-13033 branch 2 times, most recently from 3b14063 to 7fa50a6CompareJuly 2, 2021 00:37
@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche :).
I've gone through your feedback and done some of the boilerplate except for the correct output timestamp type. I'll try to do it over the weekend.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

I think there is no consensus on this yet. tz_convert, tz_localize were mentioned. I'd add tz_normalize. Any other?

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

In case we start with "naive" a timestamp we don't know the source and target timezone so both need to be specified. Or am I missing something here?

@jorisvandenbossche

Copy link
Copy Markdown
Member

What's the difference between both timezones? In my mind this is the same time zone? If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

I was thinking only of the metadata change not "materialization" of a target timezone. Having another kernel to only change metadata seems redundant.

@jorisvandenbossche

Copy link
Copy Markdown
Member

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

@jorisvandenbossche

Copy link
Copy Markdown
Member

(if we keep both source and destination timezone in the "localize" kernel, I think at least the destination timezone, if not specified, should default to be the same as the source timezone, and not "UTC", so that a user doesn't have to specify the timezone they want twice, like localize(timestamp, source_timezone="Europe/Brussels", destination_timezone="Europe/Brussels") to end up with a timestamp(unit, tz="Europe/Brussels) type column)

@jorisvandenbossche

Copy link
Copy Markdown
Member

I opened https://issues.apache.org/jira/browse/ARROW-13247 for the discussion whether we want a separate "change timezone" kernel

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

I suppose these are two different operations indeed. I've changed this to only do "localization" now.

I like force_tz as it indicates the operation is a bit "dangerous". Candidates are then:

  • force_tz
  • tz_localize
  • tz_normalize

@adamhooper

Copy link
Copy Markdown
Contributor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

It's nice that it's idiomatic if a bit verbose :)

Let's add it to the list. If we don't get to consensus here we can always call a vote on the ML.

  • force_tz
  • tz_localize
  • tz_normalize
  • local_datetime_to_zoned_datetime

@westonpace

Copy link
Copy Markdown
Member

I like all except tz_normalize. "normalize" just has too many meanings for me already.

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

And from testing, you will still need to handle the errors raised by date.h:

In [21]: arr = pa.array([pd.Timestamp("2021-03-28 02:30:00")], type=pa.timestamp("ns"))
In [22]: pc.localize(arr, options=pc.TemporalLocalizationOptions("Europe/Brussels"))
terminate called after throwing an instance of 'arrow_vendored::date::nonexistent_local_time'
what(): 2021-03-28 02:30:00.000000000 is in a gap between
2021-03-28 02:00:00 CET and
2021-03-28 03:00:00 CEST which are both equivalent to
2021-03-28 01:00:00 UTC
Aborted (core dumped)

@rok

rok commented Jul 6, 2021

Copy link
Copy Markdown
MemberAuthor

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

Thanks @jorisvandenbossche! The new option initialization was indeed problematic.

@rok
rokforce-pushed the ARROW-13033 branch 8 times, most recently from 7c1ebb5 to c5a62a9CompareJuly 7, 2021 12:16
@pitrou

Copy link
Copy Markdown
Member

I'm going to suggest assume_timezone.

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

What would be a good way to reach consensus here? A doodle poll to ML to see what people find most intuitive?

@pitrou

Copy link
Copy Markdown
Member

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You may still ask for opinions on the ML, but I would personally go with assume_timezone. Users will have to read the documentation in any case.

@rok

rok commented Aug 26, 2021

Copy link
Copy Markdown
MemberAuthor

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You mean timestamps and timezones in general are weird (because the underlying problem is counter intuitive)? If not we should really make this as simple as the underlying complexity is.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 551cb2c to 76ad88fCompareSeptember 2, 2021 11:03
@rok
rok requested a review from pitrouSeptember 2, 2021 14:56
@rok

rok commented Sep 2, 2021

Copy link
Copy Markdown
MemberAuthor

@pitrou I've changed this to assume_timezone (AssumeTimezone, AssumeTimezoneOptions).
Discussion on Zulip seems to be in favor of assume_timestamp.

Would still be good to hear @jorisvandenbossche@adamhooper@westonpace

@adamhooper

Copy link
Copy Markdown
Contributor

@rok Thanks for asking! I prefer assume_timezone, too.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be here. Is it deliberate or just a leftover?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Probably a bad rebase.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what this is for. Presumably this should be unreachable?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just to satisfy the compiler.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the status but kept the return 0 to keep he compiler happy. Please check.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 008bf23 to 87ddd31CompareSeptember 6, 2021 17:12
@rok
rok requested a review from pitrouSeptember 6, 2021 19:04
@rok

rok commented Sep 6, 2021

Copy link
Copy Markdown
MemberAuthor

CI fail seems unrelated.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
@pitrou

Copy link
Copy Markdown
Member

Ok, I've pushed some minor changes and will merge once CI is green. Thanks a lot for this @rok !

@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

Let me rebase that.

@pitrou

Copy link
Copy Markdown
Member

@rok I'm on it already.

Work.
Removing destination_timezone.
fix initialization of timezone + add python bindings
Renaming localize to tz_localize.
Adding ambiguous and nonexistent handling.
Removing R wrapper.
Reintroducing R wrapper.
Issue with date.h building on rtools4.0.
Review feedback.
tz_localize -> assume_timezone
Review feedback.
Changes to nonexistent handling.
More changes to nonexistent handling.
* Documentation changes
* Simplify kernel generation
@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
…(preserving clock-time)
This is to resolve [ARROW-13033](https://issues.apache.org/jira/browse/ARROW-13033).
Closesapache#10610 from rok/ARROW-13033
Authored-by: Rok <rok@mihevc.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rok@jorisvandenbossche@adamhooper@westonpace@pitrou
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time) - #10610

Closed
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033
Closed

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time)#10610
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033

Conversation

@rok

@rokrok commented Jun 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13033.

@github-actions

Copy link
Copy Markdown

@jorisvandenbosschejorisvandenbossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given all the discussion on the JIRA issue, can you a bit more clearly state what exactly you implemented and what part it covers?
For example, the current kernel returns int64 and not timestamp with timezone?

It also seems that the implementation is converting system time (UTC epoch) to local (naive) time, and not the other way around as the docstring says.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
Comment threaddocs/source/cpp/compute.rst Outdated
@rok
rokforce-pushed the ARROW-13033 branch 2 times, most recently from 3b14063 to 7fa50a6CompareJuly 2, 2021 00:37
@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche :).
I've gone through your feedback and done some of the boilerplate except for the correct output timestamp type. I'll try to do it over the weekend.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

I think there is no consensus on this yet. tz_convert, tz_localize were mentioned. I'd add tz_normalize. Any other?

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

In case we start with "naive" a timestamp we don't know the source and target timezone so both need to be specified. Or am I missing something here?

@jorisvandenbossche

Copy link
Copy Markdown
Member

What's the difference between both timezones? In my mind this is the same time zone? If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

I was thinking only of the metadata change not "materialization" of a target timezone. Having another kernel to only change metadata seems redundant.

@jorisvandenbossche

Copy link
Copy Markdown
Member

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

@jorisvandenbossche

Copy link
Copy Markdown
Member

(if we keep both source and destination timezone in the "localize" kernel, I think at least the destination timezone, if not specified, should default to be the same as the source timezone, and not "UTC", so that a user doesn't have to specify the timezone they want twice, like localize(timestamp, source_timezone="Europe/Brussels", destination_timezone="Europe/Brussels") to end up with a timestamp(unit, tz="Europe/Brussels) type column)

@jorisvandenbossche

Copy link
Copy Markdown
Member

I opened https://issues.apache.org/jira/browse/ARROW-13247 for the discussion whether we want a separate "change timezone" kernel

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

I suppose these are two different operations indeed. I've changed this to only do "localization" now.

I like force_tz as it indicates the operation is a bit "dangerous". Candidates are then:

  • force_tz
  • tz_localize
  • tz_normalize

@adamhooper

Copy link
Copy Markdown
Contributor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

It's nice that it's idiomatic if a bit verbose :)

Let's add it to the list. If we don't get to consensus here we can always call a vote on the ML.

  • force_tz
  • tz_localize
  • tz_normalize
  • local_datetime_to_zoned_datetime

@westonpace

Copy link
Copy Markdown
Member

I like all except tz_normalize. "normalize" just has too many meanings for me already.

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

And from testing, you will still need to handle the errors raised by date.h:

In [21]: arr = pa.array([pd.Timestamp("2021-03-28 02:30:00")], type=pa.timestamp("ns"))
In [22]: pc.localize(arr, options=pc.TemporalLocalizationOptions("Europe/Brussels"))
terminate called after throwing an instance of 'arrow_vendored::date::nonexistent_local_time'
what(): 2021-03-28 02:30:00.000000000 is in a gap between
2021-03-28 02:00:00 CET and
2021-03-28 03:00:00 CEST which are both equivalent to
2021-03-28 01:00:00 UTC
Aborted (core dumped)

@rok

rok commented Jul 6, 2021

Copy link
Copy Markdown
MemberAuthor

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

Thanks @jorisvandenbossche! The new option initialization was indeed problematic.

@rok
rokforce-pushed the ARROW-13033 branch 8 times, most recently from 7c1ebb5 to c5a62a9CompareJuly 7, 2021 12:16
@pitrou

Copy link
Copy Markdown
Member

I'm going to suggest assume_timezone.

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

What would be a good way to reach consensus here? A doodle poll to ML to see what people find most intuitive?

@pitrou

Copy link
Copy Markdown
Member

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You may still ask for opinions on the ML, but I would personally go with assume_timezone. Users will have to read the documentation in any case.

@rok

rok commented Aug 26, 2021

Copy link
Copy Markdown
MemberAuthor

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You mean timestamps and timezones in general are weird (because the underlying problem is counter intuitive)? If not we should really make this as simple as the underlying complexity is.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 551cb2c to 76ad88fCompareSeptember 2, 2021 11:03
@rok
rok requested a review from pitrouSeptember 2, 2021 14:56
@rok

rok commented Sep 2, 2021

Copy link
Copy Markdown
MemberAuthor

@pitrou I've changed this to assume_timezone (AssumeTimezone, AssumeTimezoneOptions).
Discussion on Zulip seems to be in favor of assume_timestamp.

Would still be good to hear @jorisvandenbossche@adamhooper@westonpace

@adamhooper

Copy link
Copy Markdown
Contributor

@rok Thanks for asking! I prefer assume_timezone, too.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be here. Is it deliberate or just a leftover?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Probably a bad rebase.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what this is for. Presumably this should be unreachable?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just to satisfy the compiler.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the status but kept the return 0 to keep he compiler happy. Please check.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 008bf23 to 87ddd31CompareSeptember 6, 2021 17:12
@rok
rok requested a review from pitrouSeptember 6, 2021 19:04
@rok

rok commented Sep 6, 2021

Copy link
Copy Markdown
MemberAuthor

CI fail seems unrelated.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
@pitrou

Copy link
Copy Markdown
Member

Ok, I've pushed some minor changes and will merge once CI is green. Thanks a lot for this @rok !

@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

Let me rebase that.

@pitrou

Copy link
Copy Markdown
Member

@rok I'm on it already.

Work.
Removing destination_timezone.
fix initialization of timezone + add python bindings
Renaming localize to tz_localize.
Adding ambiguous and nonexistent handling.
Removing R wrapper.
Reintroducing R wrapper.
Issue with date.h building on rtools4.0.
Review feedback.
tz_localize -> assume_timezone
Review feedback.
Changes to nonexistent handling.
More changes to nonexistent handling.
* Documentation changes
* Simplify kernel generation
@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
…(preserving clock-time)
This is to resolve [ARROW-13033](https://issues.apache.org/jira/browse/ARROW-13033).
Closesapache#10610 from rok/ARROW-13033
Authored-by: Rok <rok@mihevc.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rok@jorisvandenbossche@adamhooper@westonpace@pitrou
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time) - #10610

Closed
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033
Closed

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time)#10610
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033

Conversation

@rok

@rokrok commented Jun 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13033.

@github-actions

Copy link
Copy Markdown

@jorisvandenbosschejorisvandenbossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given all the discussion on the JIRA issue, can you a bit more clearly state what exactly you implemented and what part it covers?
For example, the current kernel returns int64 and not timestamp with timezone?

It also seems that the implementation is converting system time (UTC epoch) to local (naive) time, and not the other way around as the docstring says.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
Comment threaddocs/source/cpp/compute.rst Outdated
@rok
rokforce-pushed the ARROW-13033 branch 2 times, most recently from 3b14063 to 7fa50a6CompareJuly 2, 2021 00:37
@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche :).
I've gone through your feedback and done some of the boilerplate except for the correct output timestamp type. I'll try to do it over the weekend.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

I think there is no consensus on this yet. tz_convert, tz_localize were mentioned. I'd add tz_normalize. Any other?

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

In case we start with "naive" a timestamp we don't know the source and target timezone so both need to be specified. Or am I missing something here?

@jorisvandenbossche

Copy link
Copy Markdown
Member

What's the difference between both timezones? In my mind this is the same time zone? If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

I was thinking only of the metadata change not "materialization" of a target timezone. Having another kernel to only change metadata seems redundant.

@jorisvandenbossche

Copy link
Copy Markdown
Member

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

@jorisvandenbossche

Copy link
Copy Markdown
Member

(if we keep both source and destination timezone in the "localize" kernel, I think at least the destination timezone, if not specified, should default to be the same as the source timezone, and not "UTC", so that a user doesn't have to specify the timezone they want twice, like localize(timestamp, source_timezone="Europe/Brussels", destination_timezone="Europe/Brussels") to end up with a timestamp(unit, tz="Europe/Brussels) type column)

@jorisvandenbossche

Copy link
Copy Markdown
Member

I opened https://issues.apache.org/jira/browse/ARROW-13247 for the discussion whether we want a separate "change timezone" kernel

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

I suppose these are two different operations indeed. I've changed this to only do "localization" now.

I like force_tz as it indicates the operation is a bit "dangerous". Candidates are then:

  • force_tz
  • tz_localize
  • tz_normalize

@adamhooper

Copy link
Copy Markdown
Contributor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

It's nice that it's idiomatic if a bit verbose :)

Let's add it to the list. If we don't get to consensus here we can always call a vote on the ML.

  • force_tz
  • tz_localize
  • tz_normalize
  • local_datetime_to_zoned_datetime

@westonpace

Copy link
Copy Markdown
Member

I like all except tz_normalize. "normalize" just has too many meanings for me already.

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

And from testing, you will still need to handle the errors raised by date.h:

In [21]: arr = pa.array([pd.Timestamp("2021-03-28 02:30:00")], type=pa.timestamp("ns"))
In [22]: pc.localize(arr, options=pc.TemporalLocalizationOptions("Europe/Brussels"))
terminate called after throwing an instance of 'arrow_vendored::date::nonexistent_local_time'
what(): 2021-03-28 02:30:00.000000000 is in a gap between
2021-03-28 02:00:00 CET and
2021-03-28 03:00:00 CEST which are both equivalent to
2021-03-28 01:00:00 UTC
Aborted (core dumped)

@rok

rok commented Jul 6, 2021

Copy link
Copy Markdown
MemberAuthor

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

Thanks @jorisvandenbossche! The new option initialization was indeed problematic.

@rok
rokforce-pushed the ARROW-13033 branch 8 times, most recently from 7c1ebb5 to c5a62a9CompareJuly 7, 2021 12:16
@pitrou

Copy link
Copy Markdown
Member

I'm going to suggest assume_timezone.

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

What would be a good way to reach consensus here? A doodle poll to ML to see what people find most intuitive?

@pitrou

Copy link
Copy Markdown
Member

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You may still ask for opinions on the ML, but I would personally go with assume_timezone. Users will have to read the documentation in any case.

@rok

rok commented Aug 26, 2021

Copy link
Copy Markdown
MemberAuthor

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You mean timestamps and timezones in general are weird (because the underlying problem is counter intuitive)? If not we should really make this as simple as the underlying complexity is.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 551cb2c to 76ad88fCompareSeptember 2, 2021 11:03
@rok
rok requested a review from pitrouSeptember 2, 2021 14:56
@rok

rok commented Sep 2, 2021

Copy link
Copy Markdown
MemberAuthor

@pitrou I've changed this to assume_timezone (AssumeTimezone, AssumeTimezoneOptions).
Discussion on Zulip seems to be in favor of assume_timestamp.

Would still be good to hear @jorisvandenbossche@adamhooper@westonpace

@adamhooper

Copy link
Copy Markdown
Contributor

@rok Thanks for asking! I prefer assume_timezone, too.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be here. Is it deliberate or just a leftover?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Probably a bad rebase.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what this is for. Presumably this should be unreachable?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just to satisfy the compiler.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the status but kept the return 0 to keep he compiler happy. Please check.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 008bf23 to 87ddd31CompareSeptember 6, 2021 17:12
@rok
rok requested a review from pitrouSeptember 6, 2021 19:04
@rok

rok commented Sep 6, 2021

Copy link
Copy Markdown
MemberAuthor

CI fail seems unrelated.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
@pitrou

Copy link
Copy Markdown
Member

Ok, I've pushed some minor changes and will merge once CI is green. Thanks a lot for this @rok !

@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

Let me rebase that.

@pitrou

Copy link
Copy Markdown
Member

@rok I'm on it already.

Work.
Removing destination_timezone.
fix initialization of timezone + add python bindings
Renaming localize to tz_localize.
Adding ambiguous and nonexistent handling.
Removing R wrapper.
Reintroducing R wrapper.
Issue with date.h building on rtools4.0.
Review feedback.
tz_localize -> assume_timezone
Review feedback.
Changes to nonexistent handling.
More changes to nonexistent handling.
* Documentation changes
* Simplify kernel generation
@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
…(preserving clock-time)
This is to resolve [ARROW-13033](https://issues.apache.org/jira/browse/ARROW-13033).
Closesapache#10610 from rok/ARROW-13033
Authored-by: Rok <rok@mihevc.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rok@jorisvandenbossche@adamhooper@westonpace@pitrou
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time) - #10610

Closed
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033
Closed

ARROW-13033: [C++] Kernel to localize naive timestamps to a timezone (preserving clock-time)#10610
rok wants to merge 1 commit into
apache:masterfrom
rok:ARROW-13033

Conversation

@rok

@rokrok commented Jun 28, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13033.

@github-actions

Copy link
Copy Markdown

@jorisvandenbosschejorisvandenbossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given all the discussion on the JIRA issue, can you a bit more clearly state what exactly you implemented and what part it covers?
For example, the current kernel returns int64 and not timestamp with timezone?

It also seems that the implementation is converting system time (UTC epoch) to local (naive) time, and not the other way around as the docstring says.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
Comment threaddocs/source/cpp/compute.rst Outdated
@rok
rokforce-pushed the ARROW-13033 branch 2 times, most recently from 3b14063 to 7fa50a6CompareJuly 2, 2021 00:37
@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche :).
I've gone through your feedback and done some of the boilerplate except for the correct output timestamp type. I'll try to do it over the weekend.

(also, given all the confusion also on the JIRA, we should probably try to come up with a more explicit/descriptive name ...)

I think there is no consensus on this yet. tz_convert, tz_localize were mentioned. I'd add tz_normalize. Any other?

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

@rok can you explain the rationale of adding a source_timezone and destination_timezone to the API? What's the reason for doing it like this, instead of having a single target timezone as argument?

In case we start with "naive" a timestamp we don't know the source and target timezone so both need to be specified. Or am I missing something here?

@jorisvandenbossche

Copy link
Copy Markdown
Member

What's the difference between both timezones? In my mind this is the same time zone? If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

If you want to convert your localized timezone-aware timestamp to another timezone after localizing, you can use another kernel to do that? (a kernel we don't have yet, but one we should also add, although this is a trivial, metadata-only change)

I was thinking only of the metadata change not "materialization" of a target timezone. Having another kernel to only change metadata seems redundant.

@jorisvandenbossche

Copy link
Copy Markdown
Member

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

@jorisvandenbossche

Copy link
Copy Markdown
Member

(if we keep both source and destination timezone in the "localize" kernel, I think at least the destination timezone, if not specified, should default to be the same as the source timezone, and not "UTC", so that a user doesn't have to specify the timezone they want twice, like localize(timestamp, source_timezone="Europe/Brussels", destination_timezone="Europe/Brussels") to end up with a timestamp(unit, tz="Europe/Brussels) type column)

@jorisvandenbossche

Copy link
Copy Markdown
Member

I opened https://issues.apache.org/jira/browse/ARROW-13247 for the discussion whether we want a separate "change timezone" kernel

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Having another kernel to only change metadata seems redundant.

I don't think that's redundant, as a user will regularly want to change the timezone of a timestamp column that is already localized (already has a timezone).

I am of course coming from the point of view of pandas, where those two operations are defined as two distinct methods: tz_localize to convert from "timestamp without timezone" to "timestamp with timezone" (i.e. from naive clock time to tz-aware time) and tz_convert to convert between "timestamp with timezone" with different timezones (a metadata-only change).
From a user point of view (and also implementation-wise), those two are distinct concepts, IMO, and so I would keep them as separate kernels. (also eg R's lubridate has distinct force_tz and with_tz, respectively)

I suppose these are two different operations indeed. I've changed this to only do "localization" now.

I like force_tz as it indicates the operation is a bit "dangerous". Candidates are then:

  • force_tz
  • tz_localize
  • tz_normalize

@adamhooper

Copy link
Copy Markdown
Contributor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

@rok

rok commented Jul 2, 2021

Copy link
Copy Markdown
MemberAuthor

Since the Arrow spec is going to refer to "LocalDateTime", "Instant" and "ZonedDateTime", how about reusing terms from the spec? Something along the lines of local_datetime_to_zoned_datetime()?

It's nice that it's idiomatic if a bit verbose :)

Let's add it to the list. If we don't get to consensus here we can always call a vote on the ML.

  • force_tz
  • tz_localize
  • tz_normalize
  • local_datetime_to_zoned_datetime

@westonpace

Copy link
Copy Markdown
Member

I like all except tz_normalize. "normalize" just has too many meanings for me already.

@jorisvandenbossche

Copy link
Copy Markdown
Member

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

And from testing, you will still need to handle the errors raised by date.h:

In [21]: arr = pa.array([pd.Timestamp("2021-03-28 02:30:00")], type=pa.timestamp("ns"))
In [22]: pc.localize(arr, options=pc.TemporalLocalizationOptions("Europe/Brussels"))
terminate called after throwing an instance of 'arrow_vendored::date::nonexistent_local_time'
what(): 2021-03-28 02:30:00.000000000 is in a gap between
2021-03-28 02:00:00 CET and
2021-03-28 03:00:00 CEST which are both equivalent to
2021-03-28 01:00:00 UTC
Aborted (core dumped)

@rok

rok commented Jul 6, 2021

Copy link
Copy Markdown
MemberAuthor

@rok I was checking out this PR, and in the process wrote python bindings for the option class to be able to test it in Python, so thought to directly push that here as well. (and at the same time also fixed (I think) the initialization of the timezone, which was causing the C++ tests to fail here as well)

Thanks @jorisvandenbossche! The new option initialization was indeed problematic.

@rok
rokforce-pushed the ARROW-13033 branch 8 times, most recently from 7c1ebb5 to c5a62a9CompareJuly 7, 2021 12:16
@pitrou

Copy link
Copy Markdown
Member

I'm going to suggest assume_timezone.

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

What would be a good way to reach consensus here? A doodle poll to ML to see what people find most intuitive?

@pitrou

Copy link
Copy Markdown
Member

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You may still ask for opinions on the ML, but I would personally go with assume_timezone. Users will have to read the documentation in any case.

@rok

rok commented Aug 26, 2021

Copy link
Copy Markdown
MemberAuthor

Well, I don't think anything is intuitive here, because the semantics of timestamps in Arrow are slightly weird and surprising :-)

You mean timestamps and timezones in general are weird (because the underlying problem is counter intuitive)? If not we should really make this as simple as the underlying complexity is.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 551cb2c to 76ad88fCompareSeptember 2, 2021 11:03
@rok
rok requested a review from pitrouSeptember 2, 2021 14:56
@rok

rok commented Sep 2, 2021

Copy link
Copy Markdown
MemberAuthor

@pitrou I've changed this to assume_timezone (AssumeTimezone, AssumeTimezoneOptions).
Discussion on Zulip seems to be in favor of assume_timestamp.

Would still be good to hear @jorisvandenbossche@adamhooper@westonpace

@adamhooper

Copy link
Copy Markdown
Contributor

@rok Thanks for asking! I prefer assume_timezone, too.

Comment threadcpp/src/arrow/compute/api_scalar.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be here. Is it deliberate or just a leftover?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Probably a bad rebase.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what this is for. Presumably this should be unreachable?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was just to satisfy the compiler.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the status but kept the return 0 to keep he compiler happy. Please check.

@rok
rokforce-pushed the ARROW-13033 branch 3 times, most recently from 008bf23 to 87ddd31CompareSeptember 6, 2021 17:12
@rok
rok requested a review from pitrouSeptember 6, 2021 19:04
@rok

rok commented Sep 6, 2021

Copy link
Copy Markdown
MemberAuthor

CI fail seems unrelated.

Comment threadcpp/src/arrow/compute/kernels/scalar_temporal_test.cc Outdated
@pitrou

Copy link
Copy Markdown
Member

Ok, I've pushed some minor changes and will merge once CI is green. Thanks a lot for this @rok !

@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

Let me rebase that.

@pitrou

Copy link
Copy Markdown
Member

@rok I'm on it already.

Work.
Removing destination_timezone.
fix initialization of timezone + add python bindings
Renaming localize to tz_localize.
Adding ambiguous and nonexistent handling.
Removing R wrapper.
Reintroducing R wrapper.
Issue with date.h building on rtools4.0.
Review feedback.
tz_localize -> assume_timezone
Review feedback.
Changes to nonexistent handling.
More changes to nonexistent handling.
* Documentation changes
* Simplify kernel generation
@rok

rok commented Sep 9, 2021

Copy link
Copy Markdown
MemberAuthor

ViniciusSouzaRoque pushed a commit to s1mbi0se/arrow that referenced this pull request Oct 20, 2021
…(preserving clock-time)
This is to resolve [ARROW-13033](https://issues.apache.org/jira/browse/ARROW-13033).
Closesapache#10610 from rok/ARROW-13033
Authored-by: Rok <rok@mihevc.org>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rok@jorisvandenbossche@adamhooper@westonpace@pitrou