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

Add configurable default timezone information #197

Merged
merged 2 commits into from
Jun 9, 2021

Conversation

krisgesling
Copy link
Contributor

Description

Adds configurable default timezone information for use by

  • Default tz-info can be set with lingua_franca.time.set_default_tz
  • All datetime extractors default to now_local for anchorDate
  • All localized functions now inject a tzinfo in all tz-naive datetime objects passed as arguments. Note tz-naive objects are presumed to be in UTC as there is no perfect answer here.
    • Note this will also be done on methods that do not explicitly require tzinfo such as nice_time()
    • As such projects are encouraged to pass in timezone aware datetime objects where ever possible.
  • Timezone info injection can be enabled/disable in lingua_franca.config (default: enabled)
  • Lingua Franca should always return a timezone aware datetime object in the configured default timezone

Extends and replaces PR #180 - squashed commits and fixed failing tests.

Type of PR

  • Bugfix
  • Feature implementation

Testing

Unit tests have been updated.

@devs-mycroft devs-mycroft added the CLA: Yes Contributor License Agreement exists (see https://github.com/MycroftAI/contributors) label May 28, 2021
@ChanceNCounter
Copy link
Contributor

Sorry, lost in notification spam. Tagging for review.

@ChanceNCounter ChanceNCounter self-requested a review June 2, 2021 18:38
@ChanceNCounter
Copy link
Contributor

I would like to clarify whether the Czech datetime extractor is injecting tzinfo in all the scenarios where @JarbasAl's logic does so in the other files.

@Tony763
Copy link
Contributor

Tony763 commented Jun 4, 2021

I would like to clarify whether the Czech datetime extractor is injecting tzinfo in all the scenarios where @JarbasAl's logic does so in the other files.

Hi, @ChanceNCounter when I did a Czech support, I took a English files and did 1:1 copy. If You need to change something, write what an I will look into it. 🙂

Comment on lines 461 to 468
# Check if we need to add timezone awareness to any datetime object
if config.inject_timezones:
for key, value in kwargs.items():
if isinstance(value, datetime) and value.tzinfo is None:
kwargs[key] = to_local(value)
for idx, value in enumerate(args):
if isinstance(value, datetime) and value.tzinfo is None:
args = args[:idx] + (to_local(value),) + args[idx + 1:]
Copy link
Contributor

Choose a reason for hiding this comment

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

@krisgesling I am confused by this tuple's tupleyness

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I did a double take on it at first too.
('a') provides a string; whilst
('a',) provides a single item tuple

I've switched it out to use iterable unpacking:

args = (*args[:idx], to_local(value), *args[idx + 1:])

hopefully this is more readable, though I also don't see it being used a lot so may still confuse some people.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's significantly more readable, in that I thought the outer type was a list, but now I'm wondering why args is a tuple 👅

@ChanceNCounter
Copy link
Contributor

@Tony763 I see that now, thanks! I was just as confused by the snippet's absence from the English parser, but I've checked, and all paths add tzinfo to that temp var.

@ChanceNCounter
Copy link
Contributor

Apart from the remaining question on internal.py, I'd like to test that valid tzinfo isn't being overwritten.

@ChanceNCounter ChanceNCounter linked an issue Jun 4, 2021 that may be closed by this pull request
dt = datetime.datetime(2017, 1, 31,
13, 22, 3)
dt = datetime.datetime(2017, 1, 31,
13, 22, 3, tzinfo=default_timezone())
Copy link
Collaborator

Choose a reason for hiding this comment

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

small note, i think its good to be explicit here, but passing this is fully optional, part of what this PR does is handle this transparently

the tests only need tzinfo added in returned results, all input dates will get it appended internally

in a sense this last commit adding all those tzinfos in optional places is now removing the testing for the functionality added by this PR

as i said i think it's good to be explicit in what is being tested, this comment is merely informative, not a request for a change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it is an issue I think.

With the naive datetimes having UTC tzinfo added, from memory the tests will fail if that's not your configured default unless you explicitly pass an aware object. So it is a bit of a patch job - we really need more detailed testing that checks those different scenarios.

@krisgesling
Copy link
Contributor Author

I've just added an attempted test for using an explicitly different timezone. However it also suggests that one of the dot points from the PR description is false:

Lingua Franca should always return a timezone aware datetime object in the configured default timezone

This is also what the docstring says, but it possibly should be:

Lingua Franca should always return a timezone aware datetime object. If the method accepts a datetime object as an argument, and a timezone aware object is passed, the return value will be in the same timezone. If there is no datetime object argument, or a timezone naive object is passed, the configured default timezone will be used.

@ChanceNCounter
Copy link
Contributor

I agree, and had been reading,

always return a timezone aware datetime object in the configured default timezone [if LF had to add the tzinfo itself]

We definitely don't want to clobber tz-aware datetimes back to the configured tz!

Copy link
Contributor

@ChanceNCounter ChanceNCounter left a comment

Choose a reason for hiding this comment

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

Thought I pressed approve on my previous comment. Whoops =)

JarbasAl and others added 2 commits June 9, 2021 11:37
  - Switch None checks from == to is
  - Add default tzinfo to tests
  - remove stray commented code
  - improve readability of tuple
  - add test for extracting datetime in non-default timezone
@ChanceNCounter ChanceNCounter merged commit 3e66af9 into master Jun 9, 2021
@krisgesling
Copy link
Contributor Author

What about we just remove the word "user's":

[:obj:datetime, :obj:str]: 'datetime' is the extracted date
as a datetime object in the user's local timezone.

becomes

[:obj:datetime, :obj:str]: 'datetime' is the extracted date
as a datetime object in the local timezone.

@ChanceNCounter
Copy link
Contributor

That'd work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA: Yes Contributor License Agreement exists (see https://github.com/MycroftAI/contributors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

extract_datetime_de fails when anchor is None Should we require that all datetime params are tz aware
5 participants