1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-18 07:52:23 +01:00

(bug) invalid date display in negative timezones

This commit is contained in:
Sylvain 2023-02-03 17:25:24 +01:00
parent ed5670df07
commit 1644bc43db
7 changed files with 60 additions and 23 deletions

View File

@ -1,5 +1,7 @@
# Changelog Fab-manager
- Fix a bug: invalid date display in negative timezones
## v5.6.10 2023 February 02
- Optimized memory consumption in statistics fetcher service

View File

@ -1,6 +1,6 @@
import moment, { unitOfTime } from 'moment';
import moment, { unitOfTime } from 'moment-timezone';
import { IFablab } from '../models/fablab';
import { TDateISO, TDateISODate, TDateISOShortTime } from '../typings/date-iso';
import { IANATimeZone, TDateISO, TDateISODate, TDateISOShortTime } from '../typings/date-iso';
declare let Fablab: IFablab;
@ -46,30 +46,23 @@ export default class FormatLib {
} else {
tempDate = moment(date).toDate();
}
return Intl.DateTimeFormat(Fablab.intl_locale).format(tempDate);
return Intl.DateTimeFormat(Fablab.intl_locale, { timeZone: Fablab.timezone }).format(tempDate);
};
/**
* Parse the provided datetime or date string (as ISO8601 format) and return the equivalent Date object
*/
private static parseISOdate = (date: TDateISO|TDateISODate, res: Date = new Date()): Date => {
const isoDateMatch = (date as string)?.match(/^(\d\d\d\d)-(\d\d)-(\d\d)/);
res.setDate(parseInt(isoDateMatch[3], 10));
res.setMonth(parseInt(isoDateMatch[2], 10) - 1);
res.setFullYear(parseInt(isoDateMatch[1], 10));
return res;
private static parseISOdate = (date: TDateISO|TDateISODate): Date => {
const isoDateMatch = (date as string)?.match(/^(\d\d\d\d-\d\d-\d\d)/);
return new Date(`${isoDateMatch[1]}T12:00:00${Fablab.timezone_offset}`);
};
/**
* Parse the provided datetime or time string (as ISO8601 format) and return the equivalent Date object
*/
private static parseISOtime = (date: TDateISO|TDateISOShortTime, res: Date = new Date()): Date => {
const isoTimeMatch = (date as string)?.match(/(^|T)(\d\d):(\d\d)/);
res.setHours(parseInt(isoTimeMatch[2], 10));
res.setMinutes(parseInt(isoTimeMatch[3], 10));
return res;
private static parseISOtime = (date: TDateISO|TDateISOShortTime): Date => {
const isoTimeMatch = (date as string)?.match(/(^|T)(\d\d:\d\d)/);
return new Date(`1970-01-01T${isoTimeMatch[2]}:00${Fablab.timezone_offset}`);
};
/**
@ -89,7 +82,7 @@ export default class FormatLib {
} else {
tempDate = moment(date).toDate();
}
return Intl.DateTimeFormat(Fablab.intl_locale, { hour: 'numeric', minute: 'numeric' }).format(tempDate);
return Intl.DateTimeFormat(Fablab.intl_locale, { hour: 'numeric', minute: 'numeric', timeZone: Fablab.timezone }).format(tempDate);
};
/**

View File

@ -1,3 +1,5 @@
import { IANATimeZone, TTimezoneISO } from '../typings/date-iso';
export interface IFablab {
plansModule: boolean,
spacesModule: boolean,
@ -13,7 +15,8 @@ export interface IFablab {
fullcalendar_locale: string,
intl_locale: string,
intl_currency: string,
timezone: string,
timezone: IANATimeZone,
timezone_offset: TTimezoneISO,
weekStartingDay: string,
d3DateFormat: string,
uibDateFormat: string,

View File

@ -26,7 +26,7 @@ type TDateISOTime = `${TDateISOShortTime}:${TSeconds}`|`${TDateISOShortTime}:${T
/**
* Represent a timezone like `+0100`
*/
type TTimezoneISO = `+${THours}${TMinutes}`|`-${THours}${TMinutes}`|'Z'
type TTimezoneISO = `+${THours}${TMinutes}`|`-${THours}${TMinutes}`|`+${THours}:${TMinutes}`|`-${THours}:${TMinutes}`|'Z'
/**
* Represent a string like `2021-01-08T14:42:34.678Z` (format: ISO 8601).
@ -36,3 +36,5 @@ type TTimezoneISO = `+${THours}${TMinutes}`|`-${THours}${TMinutes}`|'Z'
* "Expression produces a union type that is too complex to represent. ts(2590)
*/
export type TDateISO = `${TDateISODate}T${TDateISOTime}${TTimezoneISO}`;
export type IANATimeZone = `${string}/${string}` | 'UTC';

View File

@ -54,6 +54,7 @@
Fablab.intl_locale = "<%= Rails.application.secrets.intl_locale %>";
Fablab.intl_currency = "<%= Rails.application.secrets.intl_currency %>";
Fablab.timezone = "<%= Time.zone.tzinfo.name %>";
Fablab.timezone_offset = "<%= Time.zone.formatted_offset %>";
Fablab.translations = {
app: {
shared: {

View File

@ -24,6 +24,7 @@ global.Fablab.fullcalendar_locale = 'fr';
global.Fablab.intl_locale = 'fr-FR';
global.Fablab.intl_currency = 'EUR';
global.Fablab.timezone = 'Europe/Paris';
global.Fablab.timezone_offset = '+01:00';
global.Fablab.translations = {
app: {
shared: {

View File

@ -3,38 +3,73 @@ import { IFablab } from 'models/fablab';
declare const Fablab: IFablab;
describe('FormatLib', () => {
test('format a date', () => {
test('format a Date object in french format', () => {
Fablab.intl_locale = 'fr-FR';
const str = FormatLib.date(new Date('2023-01-12T12:00:00+0100'));
Fablab.timezone = 'Europe/Paris';
Fablab.timezone_offset = '+01:00';
const str = FormatLib.date(new Date('2023-01-12T23:59:00+0100'));
expect(str).toBe('12/01/2023');
});
test('format a Date object in canadian format', () => {
Fablab.intl_locale = 'fr-CA';
Fablab.timezone = 'America/Toronto';
Fablab.timezone_offset = '-05:00';
const str = FormatLib.date(new Date('2023-01-12T23:59:00-0500'));
expect(str).toBe('2023-01-12');
});
test('format an iso8601 short date in french format', () => {
Fablab.intl_locale = 'fr-FR';
Fablab.timezone = 'Europe/Paris';
Fablab.timezone_offset = '+01:00';
const str = FormatLib.date('2023-01-12');
expect(str).toBe('12/01/2023');
});
test('format an iso8601 short date in canadian format', () => {
Fablab.intl_locale = 'fr-CA';
Fablab.timezone = 'America/Toronto';
Fablab.timezone_offset = '-05:00';
const str = FormatLib.date('2023-02-27');
expect(str).toBe('2023-02-27');
});
test('format an iso8601 date', () => {
test('format an iso8601 date in french format', () => {
Fablab.intl_locale = 'fr-FR';
Fablab.timezone = 'Europe/Paris';
Fablab.timezone_offset = '+01:00';
const str = FormatLib.date('2023-01-12T23:59:14+0100');
expect(str).toBe('12/01/2023');
});
test('format an iso8601 date in canadian format', () => {
Fablab.intl_locale = 'fr-CA';
Fablab.timezone = 'America/Toronto';
Fablab.timezone_offset = '-05:00';
const str = FormatLib.date('2023-01-12T23:59:14-0500');
expect(str).toBe('2023-01-12');
});
test('format a time', () => {
test('format a time from a Date object', () => {
Fablab.intl_locale = 'fr-FR';
Fablab.timezone = 'Europe/Paris';
Fablab.timezone_offset = '+01:00';
const str = FormatLib.time(new Date('2023-01-12T23:59:14+0100'));
expect(str).toBe('23:59');
});
test('format a time from a Date object in canadian format', () => {
Fablab.intl_locale = 'fr-CA';
Fablab.timezone = 'America/Toronto';
Fablab.timezone_offset = '-05:00';
const str = FormatLib.time(new Date('2023-01-12T23:59:14-0500'));
expect(str).toBe('23 h 59');
});
test('format an iso8601 short time', () => {
Fablab.intl_locale = 'fr-FR';
Fablab.timezone = 'Europe/Paris';
Fablab.timezone_offset = '+01:00';
const str = FormatLib.time('23:59');
expect(str).toBe('23:59');
});
test('format an iso8601 time', () => {
Fablab.intl_locale = 'fr-CA';
Fablab.timezone = 'America/Toronto';
Fablab.timezone_offset = '-05:00';
const str = FormatLib.time('2023-01-12T23:59:14-0500');
expect(str).toBe('23 h 59');
});