Skip to content

Format DateAxisItem ticks in different timezones correctly#3083

Merged
j9ac9k merged 6 commits intopyqtgraph:masterfrom
Gatsik:dateaxisitem-handle-dst
Jul 11, 2024
Merged

Format DateAxisItem ticks in different timezones correctly#3083
j9ac9k merged 6 commits intopyqtgraph:masterfrom
Gatsik:dateaxisitem-handle-dst

Conversation

@Gatsik
Copy link
Copy Markdown
Contributor

@Gatsik Gatsik commented Jun 30, 2024

An attempt to resolve #1389
I tried to follow the recommendations from this comment, which suggested touching less code, but somewhat failed, because my IDE trims whitespaces on save automatically (i hope, this is not a big deal)

return -roundedToHour.secsTo(local.time())


def shiftLocalTimeToUtcTime(timestamp):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i still have no idea how to properly name this function

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.

inverseUTCOffset? That's my first thought

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Going from UTC to the user timezones is sometimes called "localize". That would make this "delocalize", maybe?

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'm good w/ delocalize, but with all naming conventions, I try and conform to what Qt does upstream.

We could expand on Qt's API which has offsetFromUtc

And do:

def applyOffsetFromUtc:
    ...

def applyOffsetToUtc:
    ...

Copy link
Copy Markdown
Contributor

@NilsNemitz NilsNemitz Jul 2, 2024

Choose a reason for hiding this comment

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

That seems like a good precedent!



def calculateUtcOffset(timestamp):
return -fromSecsSinceEpoch(timestamp).offsetFromUtc()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

negative, because previous implementation returned time.timezone or time.altzone, which are negative if the local DST timezone is east of UTC, and Qt returns negatives for west

Gatsik added 3 commits July 1, 2024 23:15
hopefully make them work on different platforms correctly
without being affected by bugs in dependencies
and shiftedOffsetFromUtc to applyOffsetToUtc

(as was proposed in pyqtgraph#3083 (comment))
...when only its spacing is needed
@j9ac9k
Copy link
Copy Markdown
Member

j9ac9k commented Jul 4, 2024

Hi @Gatsik

Thanks so much for this PR, the DateAxisItem has been something elusive to me, and I always felt we should use Qt's timezone support rather than Python's...

Right now CI seems to be freaking out about unexpected locale settings (note this isn't a pytest.fail but an error being raised).

=========================== short test summary info ============================
ERROR tests/graphicsItems/test_DateAxisItem.py::test_preferred_utc_offset_respects_chosen_offset - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_preferred_utc_offset_doesnt_break_with_big_timestamps - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_utc_offset_works_with_float_timestamp - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_shift_local_time_to_utc_time_does_what_it_promises_to_do - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_tick_values_to_local_times[Berlin-backward] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_tick_values_to_local_times[Berlin-forward] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_tick_values_to_local_times[Chatham-backward] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_tick_values_to_local_times[Chatham-forward] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_tick_values_to_local_times[St_Johns-backward] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_tick_values_to_local_times[St_Johns-forward] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_tick_values_to_local_times[Lord_Howe-backward] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_tick_values_to_local_times[Lord_Howe-forward] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_hour_ticks_to_local_times_when_skip_greater_than_one[Berlin] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_hour_ticks_to_local_times_when_skip_greater_than_one[Chatham] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_hour_ticks_to_local_times_when_skip_greater_than_one[St_Johns] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_maps_hour_ticks_to_local_times_when_skip_greater_than_one[Lord_Howe] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_custom_utc_offset_works[zoomLevel0-expectedHourTickStrings0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_custom_utc_offset_works[zoomLevel1-expectedHourTickStrings1] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone0-0.001-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone1-1-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone2-60-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone3-3600-7] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone4-86400-6] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone5-604800-5] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone6-2592000-4] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone7-31536000-3] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone8-0.001-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone9-1-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone10-60-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone11-3600-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone12-86400-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone13-604800-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone14-2592000-0] - locale.Error: unsupported locale setting
ERROR tests/graphicsItems/test_DateAxisItem.py::test_extendTimeRangeForSpacing_repsects_utc_offset[localZone15-31536000-0] - locale.Error: unsupported locale setting

Weird, the locale error is only on Linux runs...

     @pytest.fixture(autouse=True)
    def use_en_us_locale():
>       locale.setlocale(locale.LC_TIME, "en_US")

tests/graphicsItems/test_DateAxisItem.py:89: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

category = 2, locale = 'en_US'

    def setlocale(category, locale=None):
    
        """ Set the locale for the given category.  The locale can be
            a string, an iterable of two strings (language code and encoding),
            or None.
    
            Iterables are converted to strings using the locale aliasing
            engine.  Locale strings are passed directly to the C lib.
    
            category may be given as one of the LC_* values.
    
        """
        if locale and not isinstance(locale, _builtin_str):
            # convert to string
            locale = normalize(_build_localename(locale))
>       return _setlocale(category, locale)
E       locale.Error: unsupported locale setting

/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/locale.py:627: Error

Per this SO post, maybe we need to set the environment variable to support different locales?

https://stackoverflow.com/a/37112094/5298841

Probably need to add that setting here? https://github.com/pyqtgraph/pyqtgraph/blob/master/.github/workflows/main.yml#L10

@Gatsik
Copy link
Copy Markdown
Contributor Author

Gatsik commented Jul 4, 2024

Per this SO post, maybe we need to set the environment variable to support different locales?

i am not sure, maybe we don't need to check day ticks at all? since the most important part is hours in the test function

@Gatsik
Copy link
Copy Markdown
Contributor Author

Gatsik commented Jul 4, 2024

Per this SO post, maybe we need to set the environment variable to support different locales?

i am not sure, maybe we don't need to check day ticks at all? since the most important part is hours in the test function

i checked, and looks like ubuntu, macos and windows all support C locale, so i can change it and see what happens

Gatsik added 2 commits July 4, 2024 21:47
fix its tests: use C locale, which seems to be
available on Windows, Linux and MacOS
@j9ac9k
Copy link
Copy Markdown
Member

j9ac9k commented Jul 11, 2024

Thanks @Gatsik for making CodeQL happy; diff looks great to me. You clearly have a better handle on DateAxisItem than I do, if you feel motivated to take on other issues, please don't hesitate :D

Fixes #1389

@j9ac9k j9ac9k merged commit bf68c6e into pyqtgraph:master Jul 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Correctly formatting DateAxisItem ticks in different timezones

3 participants