Skip to content

Commit

Permalink
Backport Datetime Helpers (#1000)
Browse files Browse the repository at this point in the history
  • Loading branch information
nihalbhatnagar authored Nov 21, 2024
1 parent 8170b15 commit c0b8206
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/odd-fans-destroy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@osdk/client": patch
---

Adds methods to extract date strings from Dates and ISO-8601 strings
15 changes: 15 additions & 0 deletions etc/client.report.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ export const createClient: (baseUrl: string, ontologyRid: string | Promise<strin
// @public
export function createPlatformClient(baseUrl: string, tokenProvider: () => Promise<string>, options?: undefined, fetchFn?: typeof globalThis.fetch): PlatformClient;

// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
//
// @public
export const extractDate: (dateTime: string) => string;

// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
//
// @public
export const extractDateInLocalTime: (date: Date) => string;

// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
//
// @public
export const extractDateInUTC: (date: Date) => string;

export { isOk }

// @public (undocumented)
Expand Down
1 change: 1 addition & 0 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"p-state": "^2.0.1",
"pino": "^9.1.0",
"pino-pretty": "^11.2.1",
"timezone-mock": "^1.3.6",
"ts-expect": "^1.3.0",
"typescript": "~5.5.4",
"zod": "^3.23.8"
Expand Down
6 changes: 6 additions & 0 deletions packages/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,9 @@ export type { PlatformClient } from "./createPlatformClient.js";
export type { Logger } from "./Logger.js";
export { createAttachmentUpload } from "./object/AttachmentUpload.js";
export type { ResultOrError } from "./ResultOrError.js";

export {
extractDate,
extractDateInLocalTime,
extractDateInUTC,
} from "./util/datetimeConverters.js";
102 changes: 102 additions & 0 deletions packages/client/src/util/datetimeConverters.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright 2023 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { register, unregister } from "timezone-mock";
import {
afterAll,
afterEach,
beforeAll,
beforeEach,
describe,
expect,
it,
} from "vitest";
import {
extractDate,
extractDateInLocalTime,
extractDateInUTC,
generateOffsetUtcString,
} from "./datetimeConverters.js";

describe("test datetime converters", () => {
beforeAll(() => {
register("Etc/GMT+5");
});

afterAll(() => {
unregister();
});

describe("test extractDate", () => {
it("should error if the date is not in UTC format", () => {
expect(() => extractDate("2021-01-01")).toThrowError(
"Invariant failed: Invalid date format. Expected ISO 8601 format, but received 2021-01-01",
);
expect(() => extractDate("2021-01-01T00:0000.000Z")).toThrowError(
"Invariant failed: Invalid date format. Expected ISO 8601 format, but received 2021-01-01",
);
});

it("should return the date part of the input string", () => {
const result = extractDate("2021-01-01T00:00:00.000Z");
expect(result).toBe("2021-01-01");
});
});

describe("test extractDateInUTC", () => {
it("should return the date in UTC given Date constructed with UTC time", () => {
const date = new Date("2021-01-01T00:00:00.000Z");
expect(date.getDate()).toBe(31);
expect(date.getUTCDate()).toBe(1);
const result = extractDateInUTC(date);
expect(result).toBe("2021-01-01");
});

it("should return the date in UTC given Date constructed with a local time", () => {
const date = new Date("2020-12-31T23:00:00.000");
expect(date.getDate()).toBe(31);
expect(date.getUTCDate()).toBe(1);
const result = extractDateInUTC(date);
expect(result).toBe("2021-01-01");
});
});

describe("test extractDateInLocalTime", () => {
it("should return the date in local time given Date constructed with local time", () => {
const date = new Date("2020-12-31T23:00:00.000");
expect(date.getDate()).toBe(31);
const result = extractDateInLocalTime(date);
expect(result).toBe("2020-12-31");
});

describe("test generating ISO String", () => {
it("should return a correct ISO 8601 string that is offset correctly", () => {
const date = new Date("2021-01-01T00:00:00.000Z");
expect(date.getDate()).toBe(31);

const result = generateOffsetUtcString(date);
expect(result).toBe("2020-12-31T19:00:00.000Z");
});
});

it("should return the date in local time given Date constructed with UTC time", () => {
const date = new Date("2021-01-01T00:00:00.000Z");
expect(date.getDate()).toBe(31);
const result = extractDateInLocalTime(date);
expect(result).toBe("2020-12-31");
});
});
});
68 changes: 68 additions & 0 deletions packages/client/src/util/datetimeConverters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2024 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import invariant from "tiny-invariant";

const isoRegex =
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?$/;

/**
* Extracts the date from a ISO 8601 formatted date time string. Throws if the input is not in the correct format.
*
* @param dateTime An ISO 8601 formatted date time string
* @returns The date part of the input string
*/
export const extractDate = (dateTime: string) => {
invariant(
dateTime.length < 33,
"Invalid date format. Provided input is too long.",
);
invariant(
isoRegex.test(dateTime),
`Invalid date format. Expected ISO 8601 format, but received ${dateTime}`,
);
return extractDateFromIsoString(dateTime);
};

/**
* Generates a string representation of the input date (YYYY-MM-DD). The resulting date string reflects the given date in UTC time.
*
* @param date
* @returns The date part of a ISO 8601 formatted date time string
*/
export const extractDateInUTC = (date: Date) => {
return extractDateFromIsoString(date.toISOString());
};

/**
* Generates a string representation of the input date (YYYY-MM-DD). The resulting date string reflects the given date in the local time zone.
*
* @param date
* @returns The date part of a ISO 8601 formatted date time string
*/
export const extractDateInLocalTime = (date: Date) => {
return extractDateFromIsoString(generateOffsetUtcString(date));
};

/** @internal */
export const generateOffsetUtcString = (date: Date) => {
const offsetMs = date.getTimezoneOffset() * 60 * 1000;
return new Date(date.getTime() - offsetMs).toISOString();
};

const extractDateFromIsoString = (dateTime: string) => {
return dateTime.split("T")[0];
};
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c0b8206

Please sign in to comment.