Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/gitpod-protocol/src/util/timeutil.ts
2500 views
1
/**
2
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
3
* Licensed under the GNU Affero General Public License (AGPL).
4
* See License.AGPL.txt in the project root for license information.
5
*/
6
7
import parseDuration from "parse-duration";
8
9
/**
10
* Returns the <code>day</code>th of the next month from <code>formDate</code>.
11
* If the next month does not have a <code>day</code>th, the last day of that
12
* month is taken.
13
* The time is copied from <code>fromDate</code>.
14
*
15
* @param fromDate
16
* @param day
17
*/
18
export function oneMonthLater(fromDate: string, day?: number): string {
19
const later = new Date(fromDate);
20
day = day || later.getDate();
21
const fromMonth = later.getMonth();
22
later.setDate(day);
23
later.setMonth(later.getMonth() + 1);
24
if (later.getMonth() - fromMonth > 1) {
25
later.setDate(0);
26
}
27
return later.toISOString();
28
}
29
export const yearsLater = (fromDate: string, years: number): string =>
30
liftDate1(fromDate, (d) => {
31
d.setUTCFullYear(d.getUTCFullYear() + years);
32
return d.toISOString();
33
});
34
35
export const addMillis = (d1: string, millis: number) =>
36
liftDate1(d1, (d1) => new Date(d1.getTime() + millis).toISOString());
37
export const durationInHours = (d1: string, d2: string) =>
38
liftDate(d1, d2, (d1, d2) => millisecondsToHours(d1.getTime() - d2.getTime()));
39
export const durationInMillis = (d1: string, d2: string) => liftDate(d1, d2, (d1, d2) => d1.getTime() - d2.getTime());
40
export const isDateGreaterOrEqual = (d1: string, d2: string): boolean =>
41
liftDate(d1, d2, (d1, d2) => d1.getTime() >= d2.getTime());
42
export const isDateSmallerOrEqual = (d1: string, d2: string | undefined) => !d2 || d1 <= d2;
43
export const isDateSmaller = (d1: string, d2: string | undefined) => !d2 || d1 < d2;
44
export const oldest = (d1: string, d2: string): string => (d1 > d2 ? d1 : d2);
45
export const earliest = (d1: string, d2: string): string => (d1 < d2 ? d1 : d2);
46
export const orderAsc = (d1: string, d2: string): number => liftDate(d1, d2, (d1, d2) => d1.getTime() - d2.getTime());
47
export const liftDate1 = <T>(d1: string, f: (d1: Date) => T): T => f(new Date(d1));
48
export const liftDate = <T>(d1: string, d2: string, f: (d1: Date, d2: Date) => T): T => f(new Date(d1), new Date(d2));
49
50
export function daysBefore(date: string, days: number): string {
51
const result = new Date(date);
52
result.setDate(result.getDate() - days);
53
return result.toISOString();
54
}
55
56
export function hoursBefore(date: string, hours: number): string {
57
const result = new Date(date);
58
result.setHours(result.getHours() - hours);
59
return result.toISOString();
60
}
61
62
export function hoursLater(date: string, hours: number): string {
63
const result = new Date(date);
64
result.setHours(result.getHours() + hours);
65
return result.toISOString();
66
}
67
68
export function secondsBefore(date: string, seconds: number): string {
69
return new Date(new Date(date).getTime() - seconds * 1000).toISOString();
70
}
71
72
export function rightAfter(date: string): string {
73
return new Date(new Date(date).getTime() + 1).toISOString();
74
}
75
76
export function rightBefore(date: string): string {
77
return new Date(new Date(date).getTime() - 1).toISOString();
78
}
79
80
export function durationLongerThanSeconds(time: number, durationSeconds: number, now: number = Date.now()): boolean {
81
return (now - time) / 1000 > durationSeconds;
82
}
83
84
export function millisecondsToHours(milliseconds: number): number {
85
return milliseconds / 1000 / 60 / 60;
86
}
87
88
export function hoursToMilliseconds(hours: number): number {
89
return hours * 60 * 60 * 1000;
90
}
91
92
export function goDurationToHumanReadable(goDuration: string): string {
93
const durationMs = parseGoDurationToMs(goDuration);
94
95
let remainingMs = durationMs;
96
const hours = Math.floor(remainingMs / (60 * 60 * 1000));
97
remainingMs = remainingMs - hours * 60 * 60 * 1000;
98
99
const minutes = Math.floor(remainingMs / (60 * 1000));
100
remainingMs = remainingMs - minutes * 60 * 1000;
101
102
const seconds = Math.floor(remainingMs / 1000);
103
remainingMs = remainingMs - seconds * 1000;
104
105
const segments: string[] = [];
106
if (hours) {
107
segments.push(`${hours} hour${hours === 1 ? "" : "s"}`);
108
}
109
if (minutes) {
110
segments.push(`${minutes} minute${minutes === 1 ? "" : "s"}`);
111
}
112
if (seconds) {
113
segments.push(`${seconds} second${seconds === 1 ? "" : "s"}`);
114
}
115
116
return segments.join(" ");
117
}
118
119
export function parseGoDurationToMs(goDuration: string): number {
120
// Handle empty or whitespace-only strings as 0 duration
121
if (!goDuration || goDuration.trim() === "") {
122
return 0;
123
}
124
125
const result = parseDuration(goDuration);
126
if (result === null || result === undefined) {
127
throw new Error(`Invalid Go duration format: ${goDuration}`);
128
}
129
return result;
130
}
131
132