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

[FW][FIX] dates: avoid timezone issues by using UTC everywhere #3398

Closed
wants to merge 3 commits into from

Conversation

fw-bot
Copy link
Collaborator

@fw-bot fw-bot commented Jan 8, 2024

The issue

Steps to reproduce:

  • change your machine timezone to Jakarta
  • enter "3/8/2023" in a cell
    => it becomes "3/7/2023"

Other steps to reproduce:

  • change your machine timezone to Jakarta
  • npm run test
    => some tests are failing.

Spreadsheet date times are naive date times, they do not carry any timezone
information. A date(time) in spreadsheet is just a number with a format
after all.

We are currently using javascript native Date objects everywhere in the code to
represent spreadsheet dates.
And we are mixing UTC (new Date(timestamp)) and localized Dates
(new Date(year, month, day, ...)) at some places. This is a mistake.

Because of an (un)lucky combination of mistakes, it mostly works by chance for
most timezones.
But going back to the faulty Jakarta case: one can notice that
INITIAL_1900_DAY is UTC+0707 while INITIAL_JS_DAY is UTC+0700 (7 minutes
offset). The timezone offset changed over time.

Some of the mistakes where we mix up things:

  • INITIAL_1900_DAY is localized, but INITIAL_JS_DAY is UTC.
  • numberToJsDate: we create the date from the value as if it was UTC,
    but then set the time as if it was localized.

The fix

The idea to
fix the issue is to avoid mixing localized and UTC Dates. To represent naive
date times, we will always use UTC Date objects.

we introduce a wrapper around the Date native object for two reasons:

  • the business code should not know or care about timezones/UTC
  • manipulating Date is error prone. It's easy to mess up local vs UTC
    (as this bug fix has shown)

For the future, we could also improve the DateTime API, compared to the poor
Date API. For stable version however, we keep the changes to the minimum and
keep the Date API

Task: : 3666703

review checklist

  • feature is organized in plugin, or UI components
  • support of duplicate sheet (deep copy)
  • in model/core: ranges are Range object, and can be adapted (adaptRanges)
  • in model/UI: ranges are strings (to show the user)
  • undo-able commands (uses this.history.update)
  • multiuser-able commands (has inverse commands and transformations where needed)
  • new/updated/removed commands are documented
  • exportable in excel
  • translations (_t("qmsdf %s", abc))
  • unit tested
  • clean commented code
  • track breaking changes
  • doc is rebuild (npm run doc)
  • status is correct in Odoo

Forward-Port-Of: #3396
Forward-Port-Of: #3375

@robodoo
Copy link
Collaborator

robodoo commented Jan 8, 2024

@fw-bot
Copy link
Collaborator Author

fw-bot commented Jan 8, 2024

@LucasLefevre @pro-odoo cherrypicking of pull request #3375 failed.

stderr:

16:22:28.991285 git.c:463               trace: built-in: git cherry-pick efd97c33d59e48429f7e861eef62302ee3f0dfde
error: Cherry-picking is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
fatal: cherry-pick failed
----------
status:

Either perform the forward-port manually (and push to this branch, proceeding as usual) or close this PR (maybe?).

In the former case, you may want to edit this PR message as well.

More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port

Remove `any`

Task: 3666703
This commit prepares the ground for a fix (next commit).

The issue
---------

Steps to reproduce:

- change your machine timezone to Jakarta
- enter "3/8/2023" in a cell
=> it becomes "3/7/2023"

Other steps to reproduce:

- change your machine timezone to Jakarta
- npm run test
=> some tests are failing.

Spreadsheet date times are naive date times, they do not carry any timezone
information. A date(time) in spreadsheet is just a number with a format
after all.

We are currently using javascript native Date objects everywhere in the code to
represent spreadsheet dates.
And we are mixing UTC (new Date(timestamp)) and localized Dates
(new Date(year, month, day, ...)) at some places. This is a mistake.

Because of an (un)lucky combination of mistakes, it mostly works by chance for
most timezones.
But going back to the faulty Jakarta case: one can notice that
INITIAL_1900_DAY is UTC+0707 while INITIAL_JS_DAY is UTC+0700 (7 minutes
offset). The timezone offset changed over time.

Some of the mistakes where we mix up things:

- INITIAL_1900_DAY is localized, but INITIAL_JS_DAY is UTC.
- numberToJsDate: we create the date from the value as if it was UTC,
  but then set the time as if it was localized.

This commit
-----------

This commit prepares the ground for the real fix (next commit). The idea to
fix the issue is to avoid mixing localized and UTC Dates. To represent naive
date times, we will always use UTC Date objects.

we introduce a wrapper around the Date native object for two reasons:
- the business code should not know or care about timezones/UTC
- manipulating Date is error prone. It's easy to mess up local vs UTC
  (as this bug fix has shown)

With this [REF] commit, the behavior does not change. We still mix localised
(`new DateTime(...)`) and UTC (`DateTime.fromTimestamp(...)`).
The change comes with the next commit.

For the future, we could also improve the `DateTime` API, compared to the poor
`Date` API. For stable version however, we keep the changes to the minimum and
keep the Date API

Task: 3666703
(see also the previous commit)

The issue
---------

Steps to reproduce:

- change your machine timezone to Jakarta
- enter "3/8/2023" in a cell
=> it becomes "3/7/2023"

Other steps to reproduce:

- change your machine timezone to Jakarta
- npm run test
=> some tests are failing.

Spreadsheet date times are naive date times, they do not carry any timezone
information. A date(time) in spreadsheet is just a number with a format
after all.

We are currently using javascript native Date objects everywhere in the code to
represent spreadsheet dates.
And we are mixing UTC (new Date(timestamp)) and localized Dates
(new Date(year, month, day, ...)) at some places. This is a mistake.

Because of an (un)lucky combination of mistakes, it mostly works by chance for
most timezones.
But going back to the faulty Jakarta case: one can notice that
INITIAL_1900_DAY is UTC+0707 while INITIAL_JS_DAY is UTC+0700 (7 minutes
offset). The timezone offset changed over time.

Some of the mistakes where we mix up things:

- INITIAL_1900_DAY is localized, but INITIAL_JS_DAY is UTC.
- numberToJsDate: we create the date from the value as if it was UTC,
  but then set the time as if it was localized.

This commit
-----------

The idea to fix the issue is to avoid mixing localized and UTC Dates.
To represent naive date times, we will always use UTC Date objects.

Task: 3666703
@LucasLefevre LucasLefevre force-pushed the saas-16.3-15.0-naive-datetime-lul-YnIc-fw branch from 1442a35 to eda6968 Compare January 9, 2024 10:32
Copy link
Collaborator

@LucasLefevre LucasLefevre left a comment

Choose a reason for hiding this comment

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

robodoo r+

robodoo pushed a commit that referenced this pull request Jan 9, 2024
Remove `any`

Task: 3666703
Part-of: #3398
robodoo pushed a commit that referenced this pull request Jan 9, 2024
This commit prepares the ground for a fix (next commit).

The issue
---------

Steps to reproduce:

- change your machine timezone to Jakarta
- enter "3/8/2023" in a cell
=> it becomes "3/7/2023"

Other steps to reproduce:

- change your machine timezone to Jakarta
- npm run test
=> some tests are failing.

Spreadsheet date times are naive date times, they do not carry any timezone
information. A date(time) in spreadsheet is just a number with a format
after all.

We are currently using javascript native Date objects everywhere in the code to
represent spreadsheet dates.
And we are mixing UTC (new Date(timestamp)) and localized Dates
(new Date(year, month, day, ...)) at some places. This is a mistake.

Because of an (un)lucky combination of mistakes, it mostly works by chance for
most timezones.
But going back to the faulty Jakarta case: one can notice that
INITIAL_1900_DAY is UTC+0707 while INITIAL_JS_DAY is UTC+0700 (7 minutes
offset). The timezone offset changed over time.

Some of the mistakes where we mix up things:

- INITIAL_1900_DAY is localized, but INITIAL_JS_DAY is UTC.
- numberToJsDate: we create the date from the value as if it was UTC,
  but then set the time as if it was localized.

This commit
-----------

This commit prepares the ground for the real fix (next commit). The idea to
fix the issue is to avoid mixing localized and UTC Dates. To represent naive
date times, we will always use UTC Date objects.

we introduce a wrapper around the Date native object for two reasons:
- the business code should not know or care about timezones/UTC
- manipulating Date is error prone. It's easy to mess up local vs UTC
  (as this bug fix has shown)

With this [REF] commit, the behavior does not change. We still mix localised
(`new DateTime(...)`) and UTC (`DateTime.fromTimestamp(...)`).
The change comes with the next commit.

For the future, we could also improve the `DateTime` API, compared to the poor
`Date` API. For stable version however, we keep the changes to the minimum and
keep the Date API

Task: 3666703
Part-of: #3398
robodoo pushed a commit that referenced this pull request Jan 9, 2024
(see also the previous commit)

The issue
---------

Steps to reproduce:

- change your machine timezone to Jakarta
- enter "3/8/2023" in a cell
=> it becomes "3/7/2023"

Other steps to reproduce:

- change your machine timezone to Jakarta
- npm run test
=> some tests are failing.

Spreadsheet date times are naive date times, they do not carry any timezone
information. A date(time) in spreadsheet is just a number with a format
after all.

We are currently using javascript native Date objects everywhere in the code to
represent spreadsheet dates.
And we are mixing UTC (new Date(timestamp)) and localized Dates
(new Date(year, month, day, ...)) at some places. This is a mistake.

Because of an (un)lucky combination of mistakes, it mostly works by chance for
most timezones.
But going back to the faulty Jakarta case: one can notice that
INITIAL_1900_DAY is UTC+0707 while INITIAL_JS_DAY is UTC+0700 (7 minutes
offset). The timezone offset changed over time.

Some of the mistakes where we mix up things:

- INITIAL_1900_DAY is localized, but INITIAL_JS_DAY is UTC.
- numberToJsDate: we create the date from the value as if it was UTC,
  but then set the time as if it was localized.

This commit
-----------

The idea to fix the issue is to avoid mixing localized and UTC Dates.
To represent naive date times, we will always use UTC Date objects.

closes #3398

Task: 3666703
Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com>
Signed-off-by: Lucas Lefèvre (lul) <lul@odoo.com>
@robodoo robodoo closed this Jan 9, 2024
@fw-bot fw-bot deleted the saas-16.3-15.0-naive-datetime-lul-YnIc-fw branch January 23, 2024 11:46
Sign up for free to 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.

3 participants