twentyhq / twenty

Building a modern alternative to Salesforce, powered by the community.
https://twenty.com
GNU Affero General Public License v3.0
15.19k stars 1.54k forks source link

Date and time formatting and timezone #5140

Open FelixMalfait opened 3 months ago

FelixMalfait commented 3 months ago

Current behavior

We've created a section within the calendar tab. Backend hasn't been implemented. And on the app's frontend we use the browser' timezone.

Screenshot 2024-04-23 at 17 38 57

Desired behavior

1. Move section to profile

We want to move this section within the Profile page as those settings are user level and will affect different parts of the app. Rename the section to "Date and time", and the subtext to "Configure how dates are displayed across the app".

2. Introduce a default timezone option "System settings

It seems like the best in class behavior is (1) saving user timezone upon signup (2) offering to change timezone when we detect that the user is travelling. That's way too complex for now. Instead we should introduce a timezone option "System settings" (which could be saved as 'system')

Note: Ideally we would also introduce "system" for date/time format for consistency. It seems that there's not built-in function to retrieve this from the browser, only hacks... So we might want to hardcode a default. But my personal preference would go for the JS hack to get the user's preferred format.

Bonus: later on we might introduce an additional option "Don't convert timezones" as some users might not want timezones to be converted (e.g. in my previous company Luckey which was doing property management for Airbnb, we always cared about the listings' timezone. When a guest said he would check-in at 3pm

3. Create and plug backend

Add timeZone, dateFormat, and timeFormat on workspaceMember model and plug it to the frontend. Default value = system for all (or system + US + 12 hours if we decide not to go with the hack)

4. Adapt the app

Adapt date fields across the app to take into account user settings for formatting and timezone. 95%+ of users will probably leave the default "system settings" parameter.

adityacodes30 commented 3 months ago

I think we can also look into having an option for the user to have a preferred time format and provide a bunch of standard options for the user to select from while doing so (in the settings perhaps). Also I would love to contribute on this

FelixMalfait commented 3 months ago

@adityacodes30 yes that's what this issue is about :), we already have the UI with the options in settings but it needs to be moved to profile (away from calendar setting page) + a bunch of other changes

adityacodes30 commented 3 months ago

Alright :) , i think i can take this up over the weekend after studying the codebase a bit, let me know if any more ideas come up

FelixMalfait commented 3 months ago

Great thanks @adityacodes30 ; when you implement the hack to guess the browsers' preferred settings (AM/PM or 24, Date format), make sure to isolate it into nice utils.

adityacodes30 commented 2 months ago

the calendar settings section will remain as is right ?

FelixMalfait commented 2 months ago

"Calendar settings" would remain where it is yes. We want to move the section related to date formatting because it will not only affect the calendar feature but also other parts of the app (e.g. every date field)

adityacodes30 commented 2 months ago

I think this should work for getting the timezone. for example

const timezone = Intl.DateTimeFormat().resolvedOptions();
console.log(timezone);

which returns

{ locale: 'en-US', calendar: 'gregory', numberingSystem: 'latn', timeZone: 'Asia/Calcutta', year: 'numeric', month: 'numeric', day: 'numeric' }

FelixMalfait commented 2 months ago

That's a good start yes! 👌

Could be something like this (not tested / there might be a cleaner way):

function getBrowserTimeZone() {
  return Intl.DateTimeFormat().resolvedOptions().timeZone;
}

function getBrowserDateTimeFormat() {
  const testDate = new Date(Date.UTC(2006, 0, 2, 15, 4, 5));
  const options = { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', timeZone: 'UTC' };
  const formatted = new Intl.DateTimeFormat(navigator.language, options).format(testDate);

  // Detect 24-hour or 12-hour time format by looking for AM/PM in the formatted string
  const timeFormat = /AM|PM/i.test(formatted) ? '12-hour' : '24-hour';

  // Detect US (MM/DD/YYYY) or UK (DD/MM/YYYY) date format by the position of the month (01) in the formatted string
  const monthFirst = formatted.indexOf('1') < formatted.indexOf('2');
  const dateFormat = monthFirst ? 'US' : 'UK';

  return { dateFormat, timeFormat };
}

To adapt with context of current code of course

adityacodes30 commented 2 months ago

yes thats what i was going for as well. Also in the current implementation, how is the application handling time across different components ? In the workspace member model we would need to add 3 properties , wouldn't it be better if we add the formats (time and date) in a single field as an object

FelixMalfait commented 2 months ago

If the format is predictable, it's better to use separate columns than json which you can't query properly. We'd only use json if there was uncertainty around the format / different object configurations. As for the handling of time you'll have to look into the code 😄

adityacodes30 commented 2 months ago

Ah alright, that makes sense , Thank You !