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

feat(DateTime): add helper to interpret input without timezone as utc time otherwise convert to utc #50

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/constants/timeZone.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import type {TimeZone} from '../typings';

export const UtcTimeZone: TimeZone = 'UTC';
export const UtcTimeZone = 'UTC';
41 changes: 24 additions & 17 deletions src/dateTime/dateTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,22 +264,13 @@ class DateTimeImpl implements DateTime {
asFloat?: boolean | undefined,
): number {
const value = DateTimeImpl.isDateTime(amount) ? amount.valueOf() : amount;
// value:
// DateTimeInput !== dayjs.ConfigType;
// Array<string, number> !== [number?, number?, number?, number?, number?, number?, number?]
// unit:
// the same problem as for startOf
// @ts-expect-error
return this._date.diff(value, unit, asFloat);
}
fromNow(withoutSuffix?: boolean | undefined): string {
return this._date.fromNow(withoutSuffix);
}
from(formaInput: DateTimeInput, withoutSuffix?: boolean): string {
const value = DateTimeImpl.isDateTime(formaInput) ? formaInput.valueOf() : formaInput;
// DateTimeInput !== dayjs.ConfigType;
// Array<string, number> !== [number?, number?, number?, number?, number?, number?, number?]
// @ts-expect-error
return this._date.from(value, withoutSuffix);
}
locale(): string;
Expand Down Expand Up @@ -569,14 +560,8 @@ function getTimestamp(input: DateTimeInput, format?: string, lang?: string) {
ts = Number(input);
} else {
const localDate = format
? // DateTimeInput !== dayjs.ConfigType;
// Array<string, number> !== [number?, number?, number?, number?, number?, number?, number?]
// @ts-expect-error
dayjs(input, format, locale, STRICT)
: // DateTimeInput !== dayjs.ConfigType;
// Array<string, number> !== [number?, number?, number?, number?, number?, number?, number?]
// @ts-expect-error
dayjs(input, undefined, locale);
? dayjs(input, format, locale, STRICT)
: dayjs(input, undefined, locale);

ts = localDate.valueOf();
}
Expand Down Expand Up @@ -623,3 +608,25 @@ export function dateTime(opt?: {

return date;
}

export function dateTimeUtc(opt?: {input?: DateTimeInput; format?: FormatInput; lang?: string}) {
const {input, format, lang} = opt || {};

const locale = dayjs.locale(lang || settings.getLocale(), undefined, true);

let ts: number;
if (DateTimeImpl.isDateTime(input) || typeof input === 'number' || input instanceof Date) {
ts = Number(input);
} else {
ts = dayjs.utc(input, format, STRICT).valueOf();
}

const date = createDateTime({
ts,
timeZone: UtcTimeZone,
offset: 0,
locale,
});

return date;
}
63 changes: 63 additions & 0 deletions src/dateTime/dateTimeUtc.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import MockDate from 'mockdate';

import {settings} from '../settings';

import {dateTimeUtc, isDateTime} from './dateTime';

const MOCKED_DATE = '2021-08-07T12:10:00';

beforeEach(() => {
MockDate.set(MOCKED_DATE);
});

afterEach(() => {
MockDate.reset();
settings.updateLocale({weekStart: 1, yearStart: 1});
});

describe('DateTimeUtc', () => {
describe('isDateTime', () => {
it('should return true in case of DateTime checking', () => {
const date = dateTimeUtc();
const result = isDateTime(date);
expect(result).toEqual(true);
});
});

describe('dateTimeUtc', () => {
it('should return now date in case of absence of input arg', () => {
const date = dateTimeUtc();
const now = new Date();
expect(date.toISOString()).toEqual(now.toISOString());
});

it('should return DateTime with UTC timeZone', () => {
const zone = dateTimeUtc().timeZone();
expect(zone).toEqual('UTC');
});

it('should return 0 offset', () => {
const date = dateTimeUtc();
const offset = date.utcOffset();
expect(offset).toEqual(0);
});

test.each<[string, string]>([
['2023-12-31', '2023-12-31T00:00:00.000Z'],
['2023-12-31T01:00', '2023-12-31T01:00:00.000Z'],
['2023-12-31T01:00Z', '2023-12-31T01:00:00.000Z'],
['2023-12-31T03:00+02:00', '2023-12-31T01:00:00.000Z'],
])('input option (%p)', (input, expected) => {
const date = dateTimeUtc({input}).toISOString();
expect(date).toEqual(expected);
});

test.each<[string, string, string]>([
['31.12.2023', 'DD.MM.YYYY', '2023-12-31T00:00:00.000Z'],
['31.12.2023 01:00', 'DD.MM.YYYY HH:mm', '2023-12-31T01:00:00.000Z'],
])('input (%p) format (%p)', (input, format, expected) => {
const date = dateTimeUtc({input, format}).toISOString();
expect(date).toEqual(expected);
});
});
});
4 changes: 2 additions & 2 deletions src/datemath/datemath.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('DateMath', () => {
const format = 'YYYY-MM-DDTHH:mm:ss.SSSZ';
let clock: SinonFakeTimers;

describe('Ошибки', () => {
describe('Issues', () => {
it('should return undefined if passed empty string', () => {
expect(dateMath.parse('')).toBe(undefined);
});
Expand Down Expand Up @@ -134,7 +134,7 @@ describe('DateMath', () => {
});
});

describe('Парс части относительной даты, начинающейся после now', () => {
describe('Parsing part after now', () => {
it('should handle negative time', () => {
const date = dateMath.parseDateMath('-2d', dateTime({input: [2014, 1, 5]}));
expect(date?.valueOf()).toEqual(dateTime({input: [2014, 1, 3]}).valueOf());
Expand Down
4 changes: 2 additions & 2 deletions src/datemath/datemath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function parse(
mathString = text.substring(index + 2);
}

time = dateTime({input: parseString});
time = dateTime({input: parseString, timeZone});
}

if (!mathString.length) {
Expand All @@ -71,7 +71,7 @@ export function parse(
}

if (isDate(text)) {
return dateTime({input: text});
return dateTime({input: text, timeZone});
}

return undefined;
Expand Down
10 changes: 10 additions & 0 deletions src/dayjs/dayjs.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'dayjs';

declare module 'dayjs' {
interface ConfigTypeMap {
// to fix inconsistent typing between dayjs and DateTime
// dayjs expects [number?, number?, number?, number?, number?, number?, number?]
// but DateTime allows Array<string | number>
dateTimeArray: Array<string | number>;
}
}
File renamed without changes.
5 changes: 3 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export {dateTime, isDateTime} from './dateTime';
export {dateTime, dateTimeUtc, isDateTime} from './dateTime';
export {isValid} from './datemath';
export {dateTimeParse} from './parser';
export {getTimeZonesList, guessUserTimeZone} from './timeZone';
export {getTimeZonesList, guessUserTimeZone, isValidTimeZone, timeZoneOffset} from './timeZone';
export type {DateTime, DateTimeInput} from './typings';
export {settings} from './settings';
export {UtcTimeZone} from './constants';
Loading