Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the timezoneOffset function #19962

Merged
merged 5 commits into from
Feb 3, 2021

Conversation

keen-wolf
Copy link
Contributor

@keen-wolf keen-wolf commented Feb 2, 2021

I hereby agree to the terms of the CLA available at: https://yandex.ru/legal/cla/?lang=en

Changelog category (leave one):

  • New Feature

Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Added timezoneOffset(datetime) function which will give the offset from UTC in seconds. This close #issue:19850.

Detailed description / Documentation draft:
Implementing this by adding a method in DateLUTImpl, we calculate the offset by consider timezone epoch also with the daylight saving change, the leap seconds is not involved now. This function may get the same result as dateDiff('second', toDateTime('somedatetime', 'time_zone_name'), toDateTime('somedatetime','UTC')). And the times that fall in the exactly changing belt which can’t be expressed by the formatted date string is also under consideration.

@robot-clickhouse robot-clickhouse added doc-alert pr-feature Pull request with new product feature labels Feb 2, 2021
@KochetovNicolai KochetovNicolai self-assigned this Feb 2, 2021
@@ -274,6 +274,23 @@ class DateLUTImpl
return res / 3600;
}


inline time_t timezoneOffset(time_t t) const
Copy link
Member

Choose a reason for hiding this comment

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

Comment to function is needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok,have fixed.


/// Calculate daylight saving offset first, ignore the leap seconds
time_t res = (lut[index].date - lut[0].date) % 86400;
res = res > 43200 ? (86400 - res) : (0 - res);
Copy link
Member

Choose a reason for hiding this comment

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

The calculation seem to be correct, but it is better to add comment about why so.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, I've appended comments.

return dateIsNotSupported(name);
}
/////need to do
using FactorTransform = ToDateImpl;
Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately, we even can't use ToDateImpl because this function is not positively monotonic (as assumed for other transforms). We should update getMonotonicityForRange

Monotonicity getMonotonicityForRange(const IDataType & type, const Field & left, const Field & right) const override

or just use ToTimeImpl for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I use ToTimeImpl now.

@@ -407,6 +407,23 @@ struct ToHourImpl
using FactorTransform = ToDateImpl;
};

struct timezoneOffsetImpl
Copy link
Member

Choose a reason for hiding this comment

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

TimezoneOffsetImpl

Copy link
Contributor Author

Choose a reason for hiding this comment

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

get fixed

/* timestamp == (Europe/Moscow) */


SELECT number,(toDateTime('1981-04-01 00:00:00', 'Europe/Moscow') + INTERVAL number * 600 SECOND) AS k, timezoneOffset(k) AS t, toUnixTimestamp(k) as s FROM numbers(200);
Copy link
Member

Choose a reason for hiding this comment

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

It would be good if test result is readable. Now, when it has > 1k rows it is not. Can we just use, e.g., 2 rows instead of 200?

Copy link
Member

Choose a reason for hiding this comment

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

The most interesting cases are the cases when daylight saving time have changed. With time just before and just after change. Also compare result with year with permanent DST (e.g. from 2011 to 2014 in Russia). Please, add comment if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

have made modifications based on your opinion
thanx~

@keen-wolf
Copy link
Contributor Author

by the way, during the test I noticed some unexpected results shown as below. I think the problem may come from the toDateTime function when processing the special timezone of 'Australia/Lord_Howe', there're many strange time skips near the DST change. need to be verified.
1
2

@KochetovNicolai
Copy link
Member

Looks like a bug indeed, but if it is, we'd better fix it in another pr.

@keen-wolf
Copy link
Contributor Author

Looks like a bug indeed, but if it is, we'd better fix it in another pr.

that's ok

@keen-wolf keen-wolf closed this Feb 3, 2021
@keen-wolf keen-wolf reopened this Feb 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr-feature Pull request with new product feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add function timezoneOffset
4 participants