mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-10-31 17:20:44 +08:00
Convert timestamp to relative format
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
This commit is contained in:
@@ -61,6 +61,6 @@
|
||||
<span> committed</span>
|
||||
{/if}
|
||||
{/if}
|
||||
<span> at </span>
|
||||
<span> </span>
|
||||
<span class="desktop-inline text-xsmall time">{formatTimestamp(commit.header.committerTime)}</span>
|
||||
</span>
|
||||
|
||||
@@ -155,6 +155,15 @@ describe("String Assertions", () => {
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ id: "hnrkj4c35uoyceb3d1dsscx8qq55cikrd1aio", expected: true },
|
||||
{ id: "0x1234567890123456789012345678901234567890", expected: false },
|
||||
])("isPeerId $id => $expected", ({ id, expected }) => {
|
||||
expect(
|
||||
utils.isPeerId(id))
|
||||
.toEqual(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ oid: "a64ae9c6d572e0ad906faa9a4a7a8d43f113278c", expected: true },
|
||||
{ oid: "a64ae9c", expected: false }
|
||||
@@ -293,3 +302,31 @@ describe("Path Manipulation", () => {
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Date Manipulation", () => {
|
||||
test.each([
|
||||
{ from: new Date("2022-01-01"), to: new Date("2022-02-01"), expected: 31 },
|
||||
{ from: new Date("2022-01-01"), to: new Date("2022-01-02"), expected: 1 },
|
||||
{ from: new Date("2022-01-01"), to: new Date("2022-01-01"), expected: 0 },
|
||||
])("getDaysPassed expected: $expected ", ({ from, to, expected }) => {
|
||||
expect(
|
||||
utils.getDaysPassed(from, to)
|
||||
).toEqual(expected);
|
||||
});
|
||||
test.each([
|
||||
{ from: new Date("2022-01-01 12:00:00"), to: new Date("2022-01-01 12:00:00"), expected: "now" },
|
||||
{ from: new Date("2022-01-01 12:00:00"), to: new Date("2022-01-01 12:00:01"), expected: "1 second ago" },
|
||||
{ from: new Date("2022-01-01 12:00:00"), to: new Date("2022-01-01 12:01:01"), expected: "1 minute ago" },
|
||||
{ from: new Date("2022-01-01 12:00:00"), to: new Date("2022-01-01 13:01:01"), expected: "1 hour ago" },
|
||||
{ from: new Date("2022-01-01 12:00:00"), to: new Date("2022-01-02 13:01:01"), expected: "yesterday" },
|
||||
{ from: new Date("2022-01-01 12:00:00"), to: new Date("2022-01-04 13:01:01"), expected: "3 days ago" },
|
||||
{ from: new Date("2022-01-01 12:00:00"), to: new Date("2022-02-02 13:01:01"), expected: "last month" },
|
||||
{ from: new Date("2022-01-01 12:00:00"), to: new Date("2022-04-02 13:01:01"), expected: "3 months ago" },
|
||||
{ from: new Date("2022-01-01 12:00:00"), to: new Date("2023-04-02 12:00:00"), expected: "Sat, 01 Jan 2022 12:00:00 GMT" },
|
||||
{ from: new Date("2022-03-05 12:00:00"), to: new Date("2026-04-02 12:00:00"), expected: "Sat, 05 Mar 2022 12:00:00 GMT" },
|
||||
])("formatTimestamp expected: $expected", ({ from, to, expected }) => {
|
||||
expect(
|
||||
utils.formatTimestamp(from.getTime() / 1000, to.getTime())
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
+41
-2
@@ -246,8 +246,35 @@ export function unixTime(): number {
|
||||
return Math.floor(Date.now() / 1000);
|
||||
}
|
||||
|
||||
export const formatTimestamp = (t: number): string => {
|
||||
return new Date(t * 1000).toLocaleString("en-EN", { dateStyle: "full", timeStyle: "long" });
|
||||
export const formatTimestamp = (timestamp: number, current = new Date().getTime()): string => {
|
||||
const units: Record<string, number> = {
|
||||
year: 24 * 60 * 60 * 1000 * 365,
|
||||
month: 24 * 60 * 60 * 1000 * 365 / 12,
|
||||
day: 24 * 60 * 60 * 1000,
|
||||
hour: 60 * 60 * 1000,
|
||||
minute: 60 * 1000,
|
||||
second: 1000
|
||||
};
|
||||
|
||||
// Multiplying timestamp with 1000 to convert from seconds to milliseconds
|
||||
timestamp = timestamp * 1000;
|
||||
const rtf = new Intl.RelativeTimeFormat('en', { numeric: "auto", style: 'long' });
|
||||
const elapsed = current - timestamp;
|
||||
|
||||
if (elapsed > units["year"]) {
|
||||
return new Date(timestamp).toUTCString(); // If it's more than a year we return early showing a Datetime string
|
||||
} else if (elapsed < 0) {
|
||||
return "now"; // If elapsed is a negative number we are dealing with an item from the future, and we return "now"
|
||||
}
|
||||
|
||||
for (const u in units) {
|
||||
if (elapsed > units[u] || u == 'second') {
|
||||
// We convert the division result to a negative number to get "XX [unit] ago"
|
||||
return rtf.format(Math.round(elapsed / units[u]) * -1, u as Intl.RelativeTimeFormatUnit);
|
||||
}
|
||||
}
|
||||
|
||||
return new Date(timestamp).toUTCString();
|
||||
};
|
||||
|
||||
// Check whether the input is a Radicle ID.
|
||||
@@ -255,6 +282,11 @@ export function isRadicleId(input: string): boolean {
|
||||
return /^rad:[a-z]+:[a-zA-Z0-9]+$/.test(input);
|
||||
}
|
||||
|
||||
// Check whether the input is a Radicle Peer ID.
|
||||
export function isPeerId(input: string): boolean {
|
||||
return /^h[a-zA-Z0-9]+$/.test(input);
|
||||
}
|
||||
|
||||
// Check whether the input is a SHA1 commit.
|
||||
export function isOid(input: string): boolean {
|
||||
return /^[a-fA-F0-9]{40}$/.test(input);
|
||||
@@ -355,6 +387,13 @@ export function parseRadicleId(urn: string): string {
|
||||
return urn.replace(/^rad:[a-z]+:/, "");
|
||||
}
|
||||
|
||||
// Get amount of days passed between two dates without including the end date
|
||||
export function getDaysPassed(from: Date, to: Date): number {
|
||||
return Math.floor(
|
||||
(to.getTime() - from.getTime()) / (24 * 60 * 60 * 1000)
|
||||
);
|
||||
}
|
||||
|
||||
// Decode a Radicle Id (URN).
|
||||
export function decodeRadicleId(urn: string): Uint8Array {
|
||||
const encoded = parseRadicleId(urn);
|
||||
|
||||
Reference in New Issue
Block a user