ARROW-13174: [C++][Compute] Add strftime kernel - #10647

Closed
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174
Closed

ARROW-13174: [C++][Compute] Add strftime kernel#10647
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174

Conversation

@rok

@rokrok commented Jul 2, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13174.

@github-actions

Copy link
Copy Markdown

@rok
rokforce-pushed the ARROW-13174 branch 3 times, most recently from 2436df1 to 45acfcdCompareJuly 9, 2021 00:06
@rok
rokforce-pushed the ARROW-13174 branch 7 times, most recently from 652d46d to 78d3ffcCompareJuly 9, 2021 22:31
@rok

rok commented Jul 9, 2021

Copy link
Copy Markdown
MemberAuthor

@westonpacestrftime kernel is almost ready for review.
I do need to take care of the string encoding.

@rok
rokforce-pushed the ARROW-13174 branch 6 times, most recently from cfa23ee to 9e8b775CompareJuly 12, 2021 23:44
@rok
rok marked this pull request as ready for review July 13, 2021 00:21

@westonpacewestonpace 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.

Thanks for doing this. Looks great.

Comment threadcpp/src/arrow/compute/api_scalar.cc 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.

Should the default format string include the trailing %z so that it is ISO-8601 compliant?

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.

Indeed. Will add.

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 that %z adds a trailing z as in the ISO format. It adds a numeric offset (eg https://www.cplusplus.com/reference/ctime/strftime/):

In [44]: datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z")
Out[44]: '2012-01-01T00:00:00+0000'

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.

According to wikipedia these are valid formats:

  1. 2021-07-15T11:24:54+00:00
  2. 2021-07-15T11:24:54Z
  3. 20210715T112454Z

%z will give us option 1. I don't have a strong preference and pandas doesn't seem to have a default.

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.

If it is significant effort I agree that +00:00 is good enough but I personally prefer Z if there is a quick option to enable it when the time zone is UTC.

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.

Switched to %Y-%m-%dT%H:%M:%SZ (2.) as default.

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.

Nit: How precise is this 30? Is it based on the default format string? If I look at 2021-07-12T23:55:41+00:00 I would think you only need ~25, maybe more if subsecond resolution. Could we base this on the resolution? It's not a big deal so if it seems like too much don't worry.

@rokrokJul 13, 2021

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.

How about a random date's string size times a fudge factor? :)

int expected_string_size = round(get_timestamp<Duration>(0, &options).size() * 1.1);
RETURN_NOT_OK(string_builder->Reserve(in.length * expected_string_size));

Comment threadpython/pyarrow/tests/test_compute.py Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13174 branch 5 times, most recently from 2033695 to 8ce4ab4CompareJuly 13, 2021 14:22
@rok

rok commented Jul 13, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @westonpace!
I've gone through it and pushed appropriate changes.

One thing I'm not sure about is if we should be using date.h for formatting here or would it be better to use system / c++ equivalents.

@pitrou

Copy link
Copy Markdown
Member

Yes, you can. Make it return a Result<const time_zone*>

@rok

rok commented Aug 17, 2021

Copy link
Copy Markdown
MemberAuthor

Yes, you can. Make it return a Result<const time_zone*>

@pitrou Done. Please review.

Comment on lines 420 to 436

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.

Please note this is only testing for C locale because that is all that is available in CI at the moment. Ideally we would cover several.

@pitrou
pitrouforce-pushed the ARROW-13174 branch 2 times, most recently from ff49e17 to 4b1d68aCompareAugust 18, 2021 14:00
@pitrou

Copy link
Copy Markdown
Member

Will merge if green.

@rok

rok commented Aug 18, 2021

Copy link
Copy Markdown
MemberAuthor

Nice! Thanks @westonpace@jorisvandenbossche@pitrou

@jorisvandenbossche

Copy link
Copy Markdown
Member

Sorry for the slow response here, but I think there are still a few behavioural aspects to fix/clarify:

  • Related to @westonpace's comment above (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), you added a "Z" to the default format. However, this is only correct if you have a UTC timezone, and not for any other timezone. For example:
    >>>ts=pd.to_datetime(["2018-03-10 09:00"]).tz_localize("US/Eastern")
    >>>tsDatetimeIndex(['2018-03-10 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq=None)
    >>>tsa=pa.array(ts)
    >>>tsa<pyarrow.lib.TimestampArrayobjectat0x7f7350b087c0>
    [
    2018-03-1014:00:00.000000000
    ]
    >>>pc.strftime(tsa)
    <pyarrow.lib.StringArrayobjectat0x7f7350b74a60>
    [
    "2018-03-10T09:00:00.000000000Z"
    ]
    So it's correctly showing the timestamp in the timezone's local time, but thus the "Z" indicator for UTC is wrong (the correct UTC time is 14:00, not 09:00).
    I think we should only add the "Z" indicator if the timezone is UTC. I am not fully sure what we should then use as default format for non-UTC timezones though: don't show any timezone information, include a numeric offset, or error.
    That would also mean that the "default" format string would depend on the input type of the data, which might not be easy / desirable.
  • I commented about the timezone handling when the initial PR had a keyword for this, but I forgot to reply after you removed that keyword (and support for local timestamps) altogether. But, what's the reasoning for disallowing local timestamps without timezone? I don't think there is any ambiguity in how they would be formatted? (after all, they represent "clock" time, which in the end is kind of a formatted string)

  • There was some discussion above about the behaviour of %S (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), where date.h / C++ handles it differently as Python or R (i.e. we are including the fractional sub-second decimals, and there is no easy way to only show integer seconds apart from casting to timestamp("s") first AFAIK).
    Since there are conflicting standards vs language implementations, there is no easy way to solve this. But I think it would be good to at least document this difference (it will be surprising for Python/R users) and how to work-around it.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche !
I think we need to address these points - I'll open a follow-up JIRA and do some work in a week or so.

  1. Indeed, current situation (Z after non UTC string) is wrong. I think your suggestion (check input timezone and append Z to default format if UTC) would be ok.
  2. I forget what the thought was at the time. But looking at our discussion it might have been a date.h limitation. I'll look into it.
  3. Agreed! We could also look into upstreaming a behavior flag to date.h but I think we'd need stronger motivation.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

@jorisvandenbossche

Copy link
Copy Markdown
Member

Thanks!

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

Follow up PR #10998

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.

6 participants

@rok@thisisnic@pitrou@jorisvandenbossche@westonpace@nealrichardson
, '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-13174: [C++][Compute] Add strftime kernel - #10647

Closed
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174
Closed

ARROW-13174: [C++][Compute] Add strftime kernel#10647
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174

Conversation

@rok

@rokrok commented Jul 2, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13174.

@github-actions

Copy link
Copy Markdown

@rok
rokforce-pushed the ARROW-13174 branch 3 times, most recently from 2436df1 to 45acfcdCompareJuly 9, 2021 00:06
@rok
rokforce-pushed the ARROW-13174 branch 7 times, most recently from 652d46d to 78d3ffcCompareJuly 9, 2021 22:31
@rok

rok commented Jul 9, 2021

Copy link
Copy Markdown
MemberAuthor

@westonpacestrftime kernel is almost ready for review.
I do need to take care of the string encoding.

@rok
rokforce-pushed the ARROW-13174 branch 6 times, most recently from cfa23ee to 9e8b775CompareJuly 12, 2021 23:44
@rok
rok marked this pull request as ready for review July 13, 2021 00:21

@westonpacewestonpace 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.

Thanks for doing this. Looks great.

Comment threadcpp/src/arrow/compute/api_scalar.cc 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.

Should the default format string include the trailing %z so that it is ISO-8601 compliant?

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.

Indeed. Will add.

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 that %z adds a trailing z as in the ISO format. It adds a numeric offset (eg https://www.cplusplus.com/reference/ctime/strftime/):

In [44]: datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z")
Out[44]: '2012-01-01T00:00:00+0000'

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.

According to wikipedia these are valid formats:

  1. 2021-07-15T11:24:54+00:00
  2. 2021-07-15T11:24:54Z
  3. 20210715T112454Z

%z will give us option 1. I don't have a strong preference and pandas doesn't seem to have a default.

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.

If it is significant effort I agree that +00:00 is good enough but I personally prefer Z if there is a quick option to enable it when the time zone is UTC.

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.

Switched to %Y-%m-%dT%H:%M:%SZ (2.) as default.

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.

Nit: How precise is this 30? Is it based on the default format string? If I look at 2021-07-12T23:55:41+00:00 I would think you only need ~25, maybe more if subsecond resolution. Could we base this on the resolution? It's not a big deal so if it seems like too much don't worry.

@rokrokJul 13, 2021

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.

How about a random date's string size times a fudge factor? :)

int expected_string_size = round(get_timestamp<Duration>(0, &options).size() * 1.1);
RETURN_NOT_OK(string_builder->Reserve(in.length * expected_string_size));

Comment threadpython/pyarrow/tests/test_compute.py Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13174 branch 5 times, most recently from 2033695 to 8ce4ab4CompareJuly 13, 2021 14:22
@rok

rok commented Jul 13, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @westonpace!
I've gone through it and pushed appropriate changes.

One thing I'm not sure about is if we should be using date.h for formatting here or would it be better to use system / c++ equivalents.

@pitrou

Copy link
Copy Markdown
Member

Yes, you can. Make it return a Result<const time_zone*>

@rok

rok commented Aug 17, 2021

Copy link
Copy Markdown
MemberAuthor

Yes, you can. Make it return a Result<const time_zone*>

@pitrou Done. Please review.

Comment on lines 420 to 436

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.

Please note this is only testing for C locale because that is all that is available in CI at the moment. Ideally we would cover several.

@pitrou
pitrouforce-pushed the ARROW-13174 branch 2 times, most recently from ff49e17 to 4b1d68aCompareAugust 18, 2021 14:00
@pitrou

Copy link
Copy Markdown
Member

Will merge if green.

@rok

rok commented Aug 18, 2021

Copy link
Copy Markdown
MemberAuthor

Nice! Thanks @westonpace@jorisvandenbossche@pitrou

@jorisvandenbossche

Copy link
Copy Markdown
Member

Sorry for the slow response here, but I think there are still a few behavioural aspects to fix/clarify:

  • Related to @westonpace's comment above (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), you added a "Z" to the default format. However, this is only correct if you have a UTC timezone, and not for any other timezone. For example:
    >>>ts=pd.to_datetime(["2018-03-10 09:00"]).tz_localize("US/Eastern")
    >>>tsDatetimeIndex(['2018-03-10 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq=None)
    >>>tsa=pa.array(ts)
    >>>tsa<pyarrow.lib.TimestampArrayobjectat0x7f7350b087c0>
    [
    2018-03-1014:00:00.000000000
    ]
    >>>pc.strftime(tsa)
    <pyarrow.lib.StringArrayobjectat0x7f7350b74a60>
    [
    "2018-03-10T09:00:00.000000000Z"
    ]
    So it's correctly showing the timestamp in the timezone's local time, but thus the "Z" indicator for UTC is wrong (the correct UTC time is 14:00, not 09:00).
    I think we should only add the "Z" indicator if the timezone is UTC. I am not fully sure what we should then use as default format for non-UTC timezones though: don't show any timezone information, include a numeric offset, or error.
    That would also mean that the "default" format string would depend on the input type of the data, which might not be easy / desirable.
  • I commented about the timezone handling when the initial PR had a keyword for this, but I forgot to reply after you removed that keyword (and support for local timestamps) altogether. But, what's the reasoning for disallowing local timestamps without timezone? I don't think there is any ambiguity in how they would be formatted? (after all, they represent "clock" time, which in the end is kind of a formatted string)

  • There was some discussion above about the behaviour of %S (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), where date.h / C++ handles it differently as Python or R (i.e. we are including the fractional sub-second decimals, and there is no easy way to only show integer seconds apart from casting to timestamp("s") first AFAIK).
    Since there are conflicting standards vs language implementations, there is no easy way to solve this. But I think it would be good to at least document this difference (it will be surprising for Python/R users) and how to work-around it.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche !
I think we need to address these points - I'll open a follow-up JIRA and do some work in a week or so.

  1. Indeed, current situation (Z after non UTC string) is wrong. I think your suggestion (check input timezone and append Z to default format if UTC) would be ok.
  2. I forget what the thought was at the time. But looking at our discussion it might have been a date.h limitation. I'll look into it.
  3. Agreed! We could also look into upstreaming a behavior flag to date.h but I think we'd need stronger motivation.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

@jorisvandenbossche

Copy link
Copy Markdown
Member

Thanks!

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

Follow up PR #10998

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.

6 participants

@rok@thisisnic@pitrou@jorisvandenbossche@westonpace@nealrichardson
, '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-13174: [C++][Compute] Add strftime kernel - #10647

Closed
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174
Closed

ARROW-13174: [C++][Compute] Add strftime kernel#10647
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174

Conversation

@rok

@rokrok commented Jul 2, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13174.

@github-actions

Copy link
Copy Markdown

@rok
rokforce-pushed the ARROW-13174 branch 3 times, most recently from 2436df1 to 45acfcdCompareJuly 9, 2021 00:06
@rok
rokforce-pushed the ARROW-13174 branch 7 times, most recently from 652d46d to 78d3ffcCompareJuly 9, 2021 22:31
@rok

rok commented Jul 9, 2021

Copy link
Copy Markdown
MemberAuthor

@westonpacestrftime kernel is almost ready for review.
I do need to take care of the string encoding.

@rok
rokforce-pushed the ARROW-13174 branch 6 times, most recently from cfa23ee to 9e8b775CompareJuly 12, 2021 23:44
@rok
rok marked this pull request as ready for review July 13, 2021 00:21

@westonpacewestonpace 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.

Thanks for doing this. Looks great.

Comment threadcpp/src/arrow/compute/api_scalar.cc 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.

Should the default format string include the trailing %z so that it is ISO-8601 compliant?

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.

Indeed. Will add.

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 that %z adds a trailing z as in the ISO format. It adds a numeric offset (eg https://www.cplusplus.com/reference/ctime/strftime/):

In [44]: datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z")
Out[44]: '2012-01-01T00:00:00+0000'

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.

According to wikipedia these are valid formats:

  1. 2021-07-15T11:24:54+00:00
  2. 2021-07-15T11:24:54Z
  3. 20210715T112454Z

%z will give us option 1. I don't have a strong preference and pandas doesn't seem to have a default.

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.

If it is significant effort I agree that +00:00 is good enough but I personally prefer Z if there is a quick option to enable it when the time zone is UTC.

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.

Switched to %Y-%m-%dT%H:%M:%SZ (2.) as default.

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.

Nit: How precise is this 30? Is it based on the default format string? If I look at 2021-07-12T23:55:41+00:00 I would think you only need ~25, maybe more if subsecond resolution. Could we base this on the resolution? It's not a big deal so if it seems like too much don't worry.

@rokrokJul 13, 2021

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.

How about a random date's string size times a fudge factor? :)

int expected_string_size = round(get_timestamp<Duration>(0, &options).size() * 1.1);
RETURN_NOT_OK(string_builder->Reserve(in.length * expected_string_size));

Comment threadpython/pyarrow/tests/test_compute.py Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13174 branch 5 times, most recently from 2033695 to 8ce4ab4CompareJuly 13, 2021 14:22
@rok

rok commented Jul 13, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @westonpace!
I've gone through it and pushed appropriate changes.

One thing I'm not sure about is if we should be using date.h for formatting here or would it be better to use system / c++ equivalents.

@pitrou

Copy link
Copy Markdown
Member

Yes, you can. Make it return a Result<const time_zone*>

@rok

rok commented Aug 17, 2021

Copy link
Copy Markdown
MemberAuthor

Yes, you can. Make it return a Result<const time_zone*>

@pitrou Done. Please review.

Comment on lines 420 to 436

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.

Please note this is only testing for C locale because that is all that is available in CI at the moment. Ideally we would cover several.

@pitrou
pitrouforce-pushed the ARROW-13174 branch 2 times, most recently from ff49e17 to 4b1d68aCompareAugust 18, 2021 14:00
@pitrou

Copy link
Copy Markdown
Member

Will merge if green.

@rok

rok commented Aug 18, 2021

Copy link
Copy Markdown
MemberAuthor

Nice! Thanks @westonpace@jorisvandenbossche@pitrou

@jorisvandenbossche

Copy link
Copy Markdown
Member

Sorry for the slow response here, but I think there are still a few behavioural aspects to fix/clarify:

  • Related to @westonpace's comment above (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), you added a "Z" to the default format. However, this is only correct if you have a UTC timezone, and not for any other timezone. For example:
    >>>ts=pd.to_datetime(["2018-03-10 09:00"]).tz_localize("US/Eastern")
    >>>tsDatetimeIndex(['2018-03-10 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq=None)
    >>>tsa=pa.array(ts)
    >>>tsa<pyarrow.lib.TimestampArrayobjectat0x7f7350b087c0>
    [
    2018-03-1014:00:00.000000000
    ]
    >>>pc.strftime(tsa)
    <pyarrow.lib.StringArrayobjectat0x7f7350b74a60>
    [
    "2018-03-10T09:00:00.000000000Z"
    ]
    So it's correctly showing the timestamp in the timezone's local time, but thus the "Z" indicator for UTC is wrong (the correct UTC time is 14:00, not 09:00).
    I think we should only add the "Z" indicator if the timezone is UTC. I am not fully sure what we should then use as default format for non-UTC timezones though: don't show any timezone information, include a numeric offset, or error.
    That would also mean that the "default" format string would depend on the input type of the data, which might not be easy / desirable.
  • I commented about the timezone handling when the initial PR had a keyword for this, but I forgot to reply after you removed that keyword (and support for local timestamps) altogether. But, what's the reasoning for disallowing local timestamps without timezone? I don't think there is any ambiguity in how they would be formatted? (after all, they represent "clock" time, which in the end is kind of a formatted string)

  • There was some discussion above about the behaviour of %S (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), where date.h / C++ handles it differently as Python or R (i.e. we are including the fractional sub-second decimals, and there is no easy way to only show integer seconds apart from casting to timestamp("s") first AFAIK).
    Since there are conflicting standards vs language implementations, there is no easy way to solve this. But I think it would be good to at least document this difference (it will be surprising for Python/R users) and how to work-around it.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche !
I think we need to address these points - I'll open a follow-up JIRA and do some work in a week or so.

  1. Indeed, current situation (Z after non UTC string) is wrong. I think your suggestion (check input timezone and append Z to default format if UTC) would be ok.
  2. I forget what the thought was at the time. But looking at our discussion it might have been a date.h limitation. I'll look into it.
  3. Agreed! We could also look into upstreaming a behavior flag to date.h but I think we'd need stronger motivation.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

@jorisvandenbossche

Copy link
Copy Markdown
Member

Thanks!

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

Follow up PR #10998

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.

6 participants

@rok@thisisnic@pitrou@jorisvandenbossche@westonpace@nealrichardson
, '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-13174: [C++][Compute] Add strftime kernel - #10647

Closed
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174
Closed

ARROW-13174: [C++][Compute] Add strftime kernel#10647
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174

Conversation

@rok

@rokrok commented Jul 2, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13174.

@github-actions

Copy link
Copy Markdown

@rok
rokforce-pushed the ARROW-13174 branch 3 times, most recently from 2436df1 to 45acfcdCompareJuly 9, 2021 00:06
@rok
rokforce-pushed the ARROW-13174 branch 7 times, most recently from 652d46d to 78d3ffcCompareJuly 9, 2021 22:31
@rok

rok commented Jul 9, 2021

Copy link
Copy Markdown
MemberAuthor

@westonpacestrftime kernel is almost ready for review.
I do need to take care of the string encoding.

@rok
rokforce-pushed the ARROW-13174 branch 6 times, most recently from cfa23ee to 9e8b775CompareJuly 12, 2021 23:44
@rok
rok marked this pull request as ready for review July 13, 2021 00:21

@westonpacewestonpace 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.

Thanks for doing this. Looks great.

Comment threadcpp/src/arrow/compute/api_scalar.cc 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.

Should the default format string include the trailing %z so that it is ISO-8601 compliant?

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.

Indeed. Will add.

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 that %z adds a trailing z as in the ISO format. It adds a numeric offset (eg https://www.cplusplus.com/reference/ctime/strftime/):

In [44]: datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z")
Out[44]: '2012-01-01T00:00:00+0000'

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.

According to wikipedia these are valid formats:

  1. 2021-07-15T11:24:54+00:00
  2. 2021-07-15T11:24:54Z
  3. 20210715T112454Z

%z will give us option 1. I don't have a strong preference and pandas doesn't seem to have a default.

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.

If it is significant effort I agree that +00:00 is good enough but I personally prefer Z if there is a quick option to enable it when the time zone is UTC.

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.

Switched to %Y-%m-%dT%H:%M:%SZ (2.) as default.

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.

Nit: How precise is this 30? Is it based on the default format string? If I look at 2021-07-12T23:55:41+00:00 I would think you only need ~25, maybe more if subsecond resolution. Could we base this on the resolution? It's not a big deal so if it seems like too much don't worry.

@rokrokJul 13, 2021

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.

How about a random date's string size times a fudge factor? :)

int expected_string_size = round(get_timestamp<Duration>(0, &options).size() * 1.1);
RETURN_NOT_OK(string_builder->Reserve(in.length * expected_string_size));

Comment threadpython/pyarrow/tests/test_compute.py Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13174 branch 5 times, most recently from 2033695 to 8ce4ab4CompareJuly 13, 2021 14:22
@rok

rok commented Jul 13, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @westonpace!
I've gone through it and pushed appropriate changes.

One thing I'm not sure about is if we should be using date.h for formatting here or would it be better to use system / c++ equivalents.

@pitrou

Copy link
Copy Markdown
Member

Yes, you can. Make it return a Result<const time_zone*>

@rok

rok commented Aug 17, 2021

Copy link
Copy Markdown
MemberAuthor

Yes, you can. Make it return a Result<const time_zone*>

@pitrou Done. Please review.

Comment on lines 420 to 436

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.

Please note this is only testing for C locale because that is all that is available in CI at the moment. Ideally we would cover several.

@pitrou
pitrouforce-pushed the ARROW-13174 branch 2 times, most recently from ff49e17 to 4b1d68aCompareAugust 18, 2021 14:00
@pitrou

Copy link
Copy Markdown
Member

Will merge if green.

@rok

rok commented Aug 18, 2021

Copy link
Copy Markdown
MemberAuthor

Nice! Thanks @westonpace@jorisvandenbossche@pitrou

@jorisvandenbossche

Copy link
Copy Markdown
Member

Sorry for the slow response here, but I think there are still a few behavioural aspects to fix/clarify:

  • Related to @westonpace's comment above (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), you added a "Z" to the default format. However, this is only correct if you have a UTC timezone, and not for any other timezone. For example:
    >>>ts=pd.to_datetime(["2018-03-10 09:00"]).tz_localize("US/Eastern")
    >>>tsDatetimeIndex(['2018-03-10 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq=None)
    >>>tsa=pa.array(ts)
    >>>tsa<pyarrow.lib.TimestampArrayobjectat0x7f7350b087c0>
    [
    2018-03-1014:00:00.000000000
    ]
    >>>pc.strftime(tsa)
    <pyarrow.lib.StringArrayobjectat0x7f7350b74a60>
    [
    "2018-03-10T09:00:00.000000000Z"
    ]
    So it's correctly showing the timestamp in the timezone's local time, but thus the "Z" indicator for UTC is wrong (the correct UTC time is 14:00, not 09:00).
    I think we should only add the "Z" indicator if the timezone is UTC. I am not fully sure what we should then use as default format for non-UTC timezones though: don't show any timezone information, include a numeric offset, or error.
    That would also mean that the "default" format string would depend on the input type of the data, which might not be easy / desirable.
  • I commented about the timezone handling when the initial PR had a keyword for this, but I forgot to reply after you removed that keyword (and support for local timestamps) altogether. But, what's the reasoning for disallowing local timestamps without timezone? I don't think there is any ambiguity in how they would be formatted? (after all, they represent "clock" time, which in the end is kind of a formatted string)

  • There was some discussion above about the behaviour of %S (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), where date.h / C++ handles it differently as Python or R (i.e. we are including the fractional sub-second decimals, and there is no easy way to only show integer seconds apart from casting to timestamp("s") first AFAIK).
    Since there are conflicting standards vs language implementations, there is no easy way to solve this. But I think it would be good to at least document this difference (it will be surprising for Python/R users) and how to work-around it.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche !
I think we need to address these points - I'll open a follow-up JIRA and do some work in a week or so.

  1. Indeed, current situation (Z after non UTC string) is wrong. I think your suggestion (check input timezone and append Z to default format if UTC) would be ok.
  2. I forget what the thought was at the time. But looking at our discussion it might have been a date.h limitation. I'll look into it.
  3. Agreed! We could also look into upstreaming a behavior flag to date.h but I think we'd need stronger motivation.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

@jorisvandenbossche

Copy link
Copy Markdown
Member

Thanks!

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

Follow up PR #10998

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.

6 participants

@rok@thisisnic@pitrou@jorisvandenbossche@westonpace@nealrichardson
, '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-13174: [C++][Compute] Add strftime kernel - #10647

Closed
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174
Closed

ARROW-13174: [C++][Compute] Add strftime kernel#10647
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174

Conversation

@rok

@rokrok commented Jul 2, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13174.

@github-actions

Copy link
Copy Markdown

@rok
rokforce-pushed the ARROW-13174 branch 3 times, most recently from 2436df1 to 45acfcdCompareJuly 9, 2021 00:06
@rok
rokforce-pushed the ARROW-13174 branch 7 times, most recently from 652d46d to 78d3ffcCompareJuly 9, 2021 22:31
@rok

rok commented Jul 9, 2021

Copy link
Copy Markdown
MemberAuthor

@westonpacestrftime kernel is almost ready for review.
I do need to take care of the string encoding.

@rok
rokforce-pushed the ARROW-13174 branch 6 times, most recently from cfa23ee to 9e8b775CompareJuly 12, 2021 23:44
@rok
rok marked this pull request as ready for review July 13, 2021 00:21

@westonpacewestonpace 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.

Thanks for doing this. Looks great.

Comment threadcpp/src/arrow/compute/api_scalar.cc 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.

Should the default format string include the trailing %z so that it is ISO-8601 compliant?

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.

Indeed. Will add.

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 that %z adds a trailing z as in the ISO format. It adds a numeric offset (eg https://www.cplusplus.com/reference/ctime/strftime/):

In [44]: datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z")
Out[44]: '2012-01-01T00:00:00+0000'

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.

According to wikipedia these are valid formats:

  1. 2021-07-15T11:24:54+00:00
  2. 2021-07-15T11:24:54Z
  3. 20210715T112454Z

%z will give us option 1. I don't have a strong preference and pandas doesn't seem to have a default.

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.

If it is significant effort I agree that +00:00 is good enough but I personally prefer Z if there is a quick option to enable it when the time zone is UTC.

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.

Switched to %Y-%m-%dT%H:%M:%SZ (2.) as default.

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.

Nit: How precise is this 30? Is it based on the default format string? If I look at 2021-07-12T23:55:41+00:00 I would think you only need ~25, maybe more if subsecond resolution. Could we base this on the resolution? It's not a big deal so if it seems like too much don't worry.

@rokrokJul 13, 2021

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.

How about a random date's string size times a fudge factor? :)

int expected_string_size = round(get_timestamp<Duration>(0, &options).size() * 1.1);
RETURN_NOT_OK(string_builder->Reserve(in.length * expected_string_size));

Comment threadpython/pyarrow/tests/test_compute.py Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13174 branch 5 times, most recently from 2033695 to 8ce4ab4CompareJuly 13, 2021 14:22
@rok

rok commented Jul 13, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @westonpace!
I've gone through it and pushed appropriate changes.

One thing I'm not sure about is if we should be using date.h for formatting here or would it be better to use system / c++ equivalents.

@pitrou

Copy link
Copy Markdown
Member

Yes, you can. Make it return a Result<const time_zone*>

@rok

rok commented Aug 17, 2021

Copy link
Copy Markdown
MemberAuthor

Yes, you can. Make it return a Result<const time_zone*>

@pitrou Done. Please review.

Comment on lines 420 to 436

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.

Please note this is only testing for C locale because that is all that is available in CI at the moment. Ideally we would cover several.

@pitrou
pitrouforce-pushed the ARROW-13174 branch 2 times, most recently from ff49e17 to 4b1d68aCompareAugust 18, 2021 14:00
@pitrou

Copy link
Copy Markdown
Member

Will merge if green.

@rok

rok commented Aug 18, 2021

Copy link
Copy Markdown
MemberAuthor

Nice! Thanks @westonpace@jorisvandenbossche@pitrou

@jorisvandenbossche

Copy link
Copy Markdown
Member

Sorry for the slow response here, but I think there are still a few behavioural aspects to fix/clarify:

  • Related to @westonpace's comment above (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), you added a "Z" to the default format. However, this is only correct if you have a UTC timezone, and not for any other timezone. For example:
    >>>ts=pd.to_datetime(["2018-03-10 09:00"]).tz_localize("US/Eastern")
    >>>tsDatetimeIndex(['2018-03-10 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq=None)
    >>>tsa=pa.array(ts)
    >>>tsa<pyarrow.lib.TimestampArrayobjectat0x7f7350b087c0>
    [
    2018-03-1014:00:00.000000000
    ]
    >>>pc.strftime(tsa)
    <pyarrow.lib.StringArrayobjectat0x7f7350b74a60>
    [
    "2018-03-10T09:00:00.000000000Z"
    ]
    So it's correctly showing the timestamp in the timezone's local time, but thus the "Z" indicator for UTC is wrong (the correct UTC time is 14:00, not 09:00).
    I think we should only add the "Z" indicator if the timezone is UTC. I am not fully sure what we should then use as default format for non-UTC timezones though: don't show any timezone information, include a numeric offset, or error.
    That would also mean that the "default" format string would depend on the input type of the data, which might not be easy / desirable.
  • I commented about the timezone handling when the initial PR had a keyword for this, but I forgot to reply after you removed that keyword (and support for local timestamps) altogether. But, what's the reasoning for disallowing local timestamps without timezone? I don't think there is any ambiguity in how they would be formatted? (after all, they represent "clock" time, which in the end is kind of a formatted string)

  • There was some discussion above about the behaviour of %S (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), where date.h / C++ handles it differently as Python or R (i.e. we are including the fractional sub-second decimals, and there is no easy way to only show integer seconds apart from casting to timestamp("s") first AFAIK).
    Since there are conflicting standards vs language implementations, there is no easy way to solve this. But I think it would be good to at least document this difference (it will be surprising for Python/R users) and how to work-around it.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche !
I think we need to address these points - I'll open a follow-up JIRA and do some work in a week or so.

  1. Indeed, current situation (Z after non UTC string) is wrong. I think your suggestion (check input timezone and append Z to default format if UTC) would be ok.
  2. I forget what the thought was at the time. But looking at our discussion it might have been a date.h limitation. I'll look into it.
  3. Agreed! We could also look into upstreaming a behavior flag to date.h but I think we'd need stronger motivation.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

@jorisvandenbossche

Copy link
Copy Markdown
Member

Thanks!

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

Follow up PR #10998

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.

6 participants

@rok@thisisnic@pitrou@jorisvandenbossche@westonpace@nealrichardson
, '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-13174: [C++][Compute] Add strftime kernel - #10647

Closed
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174
Closed

ARROW-13174: [C++][Compute] Add strftime kernel#10647
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174

Conversation

@rok

@rokrok commented Jul 2, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13174.

@github-actions

Copy link
Copy Markdown

@rok
rokforce-pushed the ARROW-13174 branch 3 times, most recently from 2436df1 to 45acfcdCompareJuly 9, 2021 00:06
@rok
rokforce-pushed the ARROW-13174 branch 7 times, most recently from 652d46d to 78d3ffcCompareJuly 9, 2021 22:31
@rok

rok commented Jul 9, 2021

Copy link
Copy Markdown
MemberAuthor

@westonpacestrftime kernel is almost ready for review.
I do need to take care of the string encoding.

@rok
rokforce-pushed the ARROW-13174 branch 6 times, most recently from cfa23ee to 9e8b775CompareJuly 12, 2021 23:44
@rok
rok marked this pull request as ready for review July 13, 2021 00:21

@westonpacewestonpace 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.

Thanks for doing this. Looks great.

Comment threadcpp/src/arrow/compute/api_scalar.cc 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.

Should the default format string include the trailing %z so that it is ISO-8601 compliant?

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.

Indeed. Will add.

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 that %z adds a trailing z as in the ISO format. It adds a numeric offset (eg https://www.cplusplus.com/reference/ctime/strftime/):

In [44]: datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z")
Out[44]: '2012-01-01T00:00:00+0000'

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.

According to wikipedia these are valid formats:

  1. 2021-07-15T11:24:54+00:00
  2. 2021-07-15T11:24:54Z
  3. 20210715T112454Z

%z will give us option 1. I don't have a strong preference and pandas doesn't seem to have a default.

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.

If it is significant effort I agree that +00:00 is good enough but I personally prefer Z if there is a quick option to enable it when the time zone is UTC.

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.

Switched to %Y-%m-%dT%H:%M:%SZ (2.) as default.

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.

Nit: How precise is this 30? Is it based on the default format string? If I look at 2021-07-12T23:55:41+00:00 I would think you only need ~25, maybe more if subsecond resolution. Could we base this on the resolution? It's not a big deal so if it seems like too much don't worry.

@rokrokJul 13, 2021

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.

How about a random date's string size times a fudge factor? :)

int expected_string_size = round(get_timestamp<Duration>(0, &options).size() * 1.1);
RETURN_NOT_OK(string_builder->Reserve(in.length * expected_string_size));

Comment threadpython/pyarrow/tests/test_compute.py Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13174 branch 5 times, most recently from 2033695 to 8ce4ab4CompareJuly 13, 2021 14:22
@rok

rok commented Jul 13, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @westonpace!
I've gone through it and pushed appropriate changes.

One thing I'm not sure about is if we should be using date.h for formatting here or would it be better to use system / c++ equivalents.

@pitrou

Copy link
Copy Markdown
Member

Yes, you can. Make it return a Result<const time_zone*>

@rok

rok commented Aug 17, 2021

Copy link
Copy Markdown
MemberAuthor

Yes, you can. Make it return a Result<const time_zone*>

@pitrou Done. Please review.

Comment on lines 420 to 436

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.

Please note this is only testing for C locale because that is all that is available in CI at the moment. Ideally we would cover several.

@pitrou
pitrouforce-pushed the ARROW-13174 branch 2 times, most recently from ff49e17 to 4b1d68aCompareAugust 18, 2021 14:00
@pitrou

Copy link
Copy Markdown
Member

Will merge if green.

@rok

rok commented Aug 18, 2021

Copy link
Copy Markdown
MemberAuthor

Nice! Thanks @westonpace@jorisvandenbossche@pitrou

@jorisvandenbossche

Copy link
Copy Markdown
Member

Sorry for the slow response here, but I think there are still a few behavioural aspects to fix/clarify:

  • Related to @westonpace's comment above (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), you added a "Z" to the default format. However, this is only correct if you have a UTC timezone, and not for any other timezone. For example:
    >>>ts=pd.to_datetime(["2018-03-10 09:00"]).tz_localize("US/Eastern")
    >>>tsDatetimeIndex(['2018-03-10 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq=None)
    >>>tsa=pa.array(ts)
    >>>tsa<pyarrow.lib.TimestampArrayobjectat0x7f7350b087c0>
    [
    2018-03-1014:00:00.000000000
    ]
    >>>pc.strftime(tsa)
    <pyarrow.lib.StringArrayobjectat0x7f7350b74a60>
    [
    "2018-03-10T09:00:00.000000000Z"
    ]
    So it's correctly showing the timestamp in the timezone's local time, but thus the "Z" indicator for UTC is wrong (the correct UTC time is 14:00, not 09:00).
    I think we should only add the "Z" indicator if the timezone is UTC. I am not fully sure what we should then use as default format for non-UTC timezones though: don't show any timezone information, include a numeric offset, or error.
    That would also mean that the "default" format string would depend on the input type of the data, which might not be easy / desirable.
  • I commented about the timezone handling when the initial PR had a keyword for this, but I forgot to reply after you removed that keyword (and support for local timestamps) altogether. But, what's the reasoning for disallowing local timestamps without timezone? I don't think there is any ambiguity in how they would be formatted? (after all, they represent "clock" time, which in the end is kind of a formatted string)

  • There was some discussion above about the behaviour of %S (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), where date.h / C++ handles it differently as Python or R (i.e. we are including the fractional sub-second decimals, and there is no easy way to only show integer seconds apart from casting to timestamp("s") first AFAIK).
    Since there are conflicting standards vs language implementations, there is no easy way to solve this. But I think it would be good to at least document this difference (it will be surprising for Python/R users) and how to work-around it.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche !
I think we need to address these points - I'll open a follow-up JIRA and do some work in a week or so.

  1. Indeed, current situation (Z after non UTC string) is wrong. I think your suggestion (check input timezone and append Z to default format if UTC) would be ok.
  2. I forget what the thought was at the time. But looking at our discussion it might have been a date.h limitation. I'll look into it.
  3. Agreed! We could also look into upstreaming a behavior flag to date.h but I think we'd need stronger motivation.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

@jorisvandenbossche

Copy link
Copy Markdown
Member

Thanks!

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

Follow up PR #10998

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.

6 participants

@rok@thisisnic@pitrou@jorisvandenbossche@westonpace@nealrichardson
, '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-13174: [C++][Compute] Add strftime kernel - #10647

Closed
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174
Closed

ARROW-13174: [C++][Compute] Add strftime kernel#10647
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174

Conversation

@rok

@rokrok commented Jul 2, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13174.

@github-actions

Copy link
Copy Markdown

@rok
rokforce-pushed the ARROW-13174 branch 3 times, most recently from 2436df1 to 45acfcdCompareJuly 9, 2021 00:06
@rok
rokforce-pushed the ARROW-13174 branch 7 times, most recently from 652d46d to 78d3ffcCompareJuly 9, 2021 22:31
@rok

rok commented Jul 9, 2021

Copy link
Copy Markdown
MemberAuthor

@westonpacestrftime kernel is almost ready for review.
I do need to take care of the string encoding.

@rok
rokforce-pushed the ARROW-13174 branch 6 times, most recently from cfa23ee to 9e8b775CompareJuly 12, 2021 23:44
@rok
rok marked this pull request as ready for review July 13, 2021 00:21

@westonpacewestonpace 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.

Thanks for doing this. Looks great.

Comment threadcpp/src/arrow/compute/api_scalar.cc 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.

Should the default format string include the trailing %z so that it is ISO-8601 compliant?

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.

Indeed. Will add.

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 that %z adds a trailing z as in the ISO format. It adds a numeric offset (eg https://www.cplusplus.com/reference/ctime/strftime/):

In [44]: datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z")
Out[44]: '2012-01-01T00:00:00+0000'

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.

According to wikipedia these are valid formats:

  1. 2021-07-15T11:24:54+00:00
  2. 2021-07-15T11:24:54Z
  3. 20210715T112454Z

%z will give us option 1. I don't have a strong preference and pandas doesn't seem to have a default.

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.

If it is significant effort I agree that +00:00 is good enough but I personally prefer Z if there is a quick option to enable it when the time zone is UTC.

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.

Switched to %Y-%m-%dT%H:%M:%SZ (2.) as default.

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.

Nit: How precise is this 30? Is it based on the default format string? If I look at 2021-07-12T23:55:41+00:00 I would think you only need ~25, maybe more if subsecond resolution. Could we base this on the resolution? It's not a big deal so if it seems like too much don't worry.

@rokrokJul 13, 2021

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.

How about a random date's string size times a fudge factor? :)

int expected_string_size = round(get_timestamp<Duration>(0, &options).size() * 1.1);
RETURN_NOT_OK(string_builder->Reserve(in.length * expected_string_size));

Comment threadpython/pyarrow/tests/test_compute.py Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13174 branch 5 times, most recently from 2033695 to 8ce4ab4CompareJuly 13, 2021 14:22
@rok

rok commented Jul 13, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @westonpace!
I've gone through it and pushed appropriate changes.

One thing I'm not sure about is if we should be using date.h for formatting here or would it be better to use system / c++ equivalents.

@pitrou

Copy link
Copy Markdown
Member

Yes, you can. Make it return a Result<const time_zone*>

@rok

rok commented Aug 17, 2021

Copy link
Copy Markdown
MemberAuthor

Yes, you can. Make it return a Result<const time_zone*>

@pitrou Done. Please review.

Comment on lines 420 to 436

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.

Please note this is only testing for C locale because that is all that is available in CI at the moment. Ideally we would cover several.

@pitrou
pitrouforce-pushed the ARROW-13174 branch 2 times, most recently from ff49e17 to 4b1d68aCompareAugust 18, 2021 14:00
@pitrou

Copy link
Copy Markdown
Member

Will merge if green.

@rok

rok commented Aug 18, 2021

Copy link
Copy Markdown
MemberAuthor

Nice! Thanks @westonpace@jorisvandenbossche@pitrou

@jorisvandenbossche

Copy link
Copy Markdown
Member

Sorry for the slow response here, but I think there are still a few behavioural aspects to fix/clarify:

  • Related to @westonpace's comment above (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), you added a "Z" to the default format. However, this is only correct if you have a UTC timezone, and not for any other timezone. For example:
    >>>ts=pd.to_datetime(["2018-03-10 09:00"]).tz_localize("US/Eastern")
    >>>tsDatetimeIndex(['2018-03-10 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq=None)
    >>>tsa=pa.array(ts)
    >>>tsa<pyarrow.lib.TimestampArrayobjectat0x7f7350b087c0>
    [
    2018-03-1014:00:00.000000000
    ]
    >>>pc.strftime(tsa)
    <pyarrow.lib.StringArrayobjectat0x7f7350b74a60>
    [
    "2018-03-10T09:00:00.000000000Z"
    ]
    So it's correctly showing the timestamp in the timezone's local time, but thus the "Z" indicator for UTC is wrong (the correct UTC time is 14:00, not 09:00).
    I think we should only add the "Z" indicator if the timezone is UTC. I am not fully sure what we should then use as default format for non-UTC timezones though: don't show any timezone information, include a numeric offset, or error.
    That would also mean that the "default" format string would depend on the input type of the data, which might not be easy / desirable.
  • I commented about the timezone handling when the initial PR had a keyword for this, but I forgot to reply after you removed that keyword (and support for local timestamps) altogether. But, what's the reasoning for disallowing local timestamps without timezone? I don't think there is any ambiguity in how they would be formatted? (after all, they represent "clock" time, which in the end is kind of a formatted string)

  • There was some discussion above about the behaviour of %S (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), where date.h / C++ handles it differently as Python or R (i.e. we are including the fractional sub-second decimals, and there is no easy way to only show integer seconds apart from casting to timestamp("s") first AFAIK).
    Since there are conflicting standards vs language implementations, there is no easy way to solve this. But I think it would be good to at least document this difference (it will be surprising for Python/R users) and how to work-around it.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche !
I think we need to address these points - I'll open a follow-up JIRA and do some work in a week or so.

  1. Indeed, current situation (Z after non UTC string) is wrong. I think your suggestion (check input timezone and append Z to default format if UTC) would be ok.
  2. I forget what the thought was at the time. But looking at our discussion it might have been a date.h limitation. I'll look into it.
  3. Agreed! We could also look into upstreaming a behavior flag to date.h but I think we'd need stronger motivation.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

@jorisvandenbossche

Copy link
Copy Markdown
Member

Thanks!

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

Follow up PR #10998

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.

6 participants

@rok@thisisnic@pitrou@jorisvandenbossche@westonpace@nealrichardson
, '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-13174: [C++][Compute] Add strftime kernel - #10647

Closed
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174
Closed

ARROW-13174: [C++][Compute] Add strftime kernel#10647
rok wants to merge 10 commits into
apache:masterfrom
rok:ARROW-13174

Conversation

@rok

@rokrok commented Jul 2, 2021

Copy link
Copy Markdown
Member

This is to resolve ARROW-13174.

@github-actions

Copy link
Copy Markdown

@rok
rokforce-pushed the ARROW-13174 branch 3 times, most recently from 2436df1 to 45acfcdCompareJuly 9, 2021 00:06
@rok
rokforce-pushed the ARROW-13174 branch 7 times, most recently from 652d46d to 78d3ffcCompareJuly 9, 2021 22:31
@rok

rok commented Jul 9, 2021

Copy link
Copy Markdown
MemberAuthor

@westonpacestrftime kernel is almost ready for review.
I do need to take care of the string encoding.

@rok
rokforce-pushed the ARROW-13174 branch 6 times, most recently from cfa23ee to 9e8b775CompareJuly 12, 2021 23:44
@rok
rok marked this pull request as ready for review July 13, 2021 00:21

@westonpacewestonpace 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.

Thanks for doing this. Looks great.

Comment threadcpp/src/arrow/compute/api_scalar.cc 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.

Should the default format string include the trailing %z so that it is ISO-8601 compliant?

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.

Indeed. Will add.

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 that %z adds a trailing z as in the ISO format. It adds a numeric offset (eg https://www.cplusplus.com/reference/ctime/strftime/):

In [44]: datetime.datetime(2012, 1, 1, tzinfo=datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z")
Out[44]: '2012-01-01T00:00:00+0000'

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.

According to wikipedia these are valid formats:

  1. 2021-07-15T11:24:54+00:00
  2. 2021-07-15T11:24:54Z
  3. 20210715T112454Z

%z will give us option 1. I don't have a strong preference and pandas doesn't seem to have a default.

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.

If it is significant effort I agree that +00:00 is good enough but I personally prefer Z if there is a quick option to enable it when the time zone is UTC.

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.

Switched to %Y-%m-%dT%H:%M:%SZ (2.) as default.

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.

Nit: How precise is this 30? Is it based on the default format string? If I look at 2021-07-12T23:55:41+00:00 I would think you only need ~25, maybe more if subsecond resolution. Could we base this on the resolution? It's not a big deal so if it seems like too much don't worry.

@rokrokJul 13, 2021

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.

How about a random date's string size times a fudge factor? :)

int expected_string_size = round(get_timestamp<Duration>(0, &options).size() * 1.1);
RETURN_NOT_OK(string_builder->Reserve(in.length * expected_string_size));

Comment threadpython/pyarrow/tests/test_compute.py Outdated
Comment threadcpp/src/arrow/compute/kernels/scalar_temporal.cc Outdated
@rok
rokforce-pushed the ARROW-13174 branch 5 times, most recently from 2033695 to 8ce4ab4CompareJuly 13, 2021 14:22
@rok

rok commented Jul 13, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @westonpace!
I've gone through it and pushed appropriate changes.

One thing I'm not sure about is if we should be using date.h for formatting here or would it be better to use system / c++ equivalents.

@pitrou

Copy link
Copy Markdown
Member

Yes, you can. Make it return a Result<const time_zone*>

@rok

rok commented Aug 17, 2021

Copy link
Copy Markdown
MemberAuthor

Yes, you can. Make it return a Result<const time_zone*>

@pitrou Done. Please review.

Comment on lines 420 to 436

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.

Please note this is only testing for C locale because that is all that is available in CI at the moment. Ideally we would cover several.

@pitrou
pitrouforce-pushed the ARROW-13174 branch 2 times, most recently from ff49e17 to 4b1d68aCompareAugust 18, 2021 14:00
@pitrou

Copy link
Copy Markdown
Member

Will merge if green.

@rok

rok commented Aug 18, 2021

Copy link
Copy Markdown
MemberAuthor

Nice! Thanks @westonpace@jorisvandenbossche@pitrou

@jorisvandenbossche

Copy link
Copy Markdown
Member

Sorry for the slow response here, but I think there are still a few behavioural aspects to fix/clarify:

  • Related to @westonpace's comment above (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), you added a "Z" to the default format. However, this is only correct if you have a UTC timezone, and not for any other timezone. For example:
    >>>ts=pd.to_datetime(["2018-03-10 09:00"]).tz_localize("US/Eastern")
    >>>tsDatetimeIndex(['2018-03-10 09:00:00-05:00'], dtype='datetime64[ns, US/Eastern]', freq=None)
    >>>tsa=pa.array(ts)
    >>>tsa<pyarrow.lib.TimestampArrayobjectat0x7f7350b087c0>
    [
    2018-03-1014:00:00.000000000
    ]
    >>>pc.strftime(tsa)
    <pyarrow.lib.StringArrayobjectat0x7f7350b74a60>
    [
    "2018-03-10T09:00:00.000000000Z"
    ]
    So it's correctly showing the timestamp in the timezone's local time, but thus the "Z" indicator for UTC is wrong (the correct UTC time is 14:00, not 09:00).
    I think we should only add the "Z" indicator if the timezone is UTC. I am not fully sure what we should then use as default format for non-UTC timezones though: don't show any timezone information, include a numeric offset, or error.
    That would also mean that the "default" format string would depend on the input type of the data, which might not be easy / desirable.
  • I commented about the timezone handling when the initial PR had a keyword for this, but I forgot to reply after you removed that keyword (and support for local timestamps) altogether. But, what's the reasoning for disallowing local timestamps without timezone? I don't think there is any ambiguity in how they would be formatted? (after all, they represent "clock" time, which in the end is kind of a formatted string)

  • There was some discussion above about the behaviour of %S (ARROW-13174: [C++][Compute] Add strftime kernel #10647 (comment)), where date.h / C++ handles it differently as Python or R (i.e. we are including the fractional sub-second decimals, and there is no easy way to only show integer seconds apart from casting to timestamp("s") first AFAIK).
    Since there are conflicting standards vs language implementations, there is no easy way to solve this. But I think it would be good to at least document this difference (it will be surprising for Python/R users) and how to work-around it.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

Thanks for the review @jorisvandenbossche !
I think we need to address these points - I'll open a follow-up JIRA and do some work in a week or so.

  1. Indeed, current situation (Z after non UTC string) is wrong. I think your suggestion (check input timezone and append Z to default format if UTC) would be ok.
  2. I forget what the thought was at the time. But looking at our discussion it might have been a date.h limitation. I'll look into it.
  3. Agreed! We could also look into upstreaming a behavior flag to date.h but I think we'd need stronger motivation.

@rok

rok commented Aug 20, 2021

Copy link
Copy Markdown
MemberAuthor

@jorisvandenbossche

Copy link
Copy Markdown
Member

Thanks!

@rok

rok commented Aug 25, 2021

Copy link
Copy Markdown
MemberAuthor

Follow up PR #10998

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.

6 participants

@rok@thisisnic@pitrou@jorisvandenbossche@westonpace@nealrichardson