odoo/o-spreadsheet#3396

Created by fw-bot
Merged at 651f9bbae038b7025656e58f10e5fd78bc7374fb

Statuses:

label
odoo:saas-16.1-15.0-naive-datetime-lul-SpTq-fw
head
cb7a33b30de53d1e674f5944e855f75c49c02331
merged
10 months ago by BI, Lucas Lefèvre (lul)
odoo/o-spreadsheet
15.0 #3375
saas-15.2 #3392
16.0 #3395
saas-16.1 #3396
saas-16.2 #3397
saas-16.3 #3398
saas-16.4 #3405
17.0 #3407
master #3415

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

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: #3395
Forward-Port-Of: #3375