-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
155 lines (134 loc) · 6.09 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Utility function to format time in human-readable "time ago" format.
function showtimeago(dateParam) {
try {
const MONTH_NAMES = [
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
// Helper function to get the ordinal suffix of a number
function getOrdinalNum(n) {
return n + (n > 0 ? ['th', 'st', 'nd', 'rd'][(n > 3 && n < 21) || n % 10 > 3 ? 0 : n % 10] : '');
}
// Helper function to format the date
function getFormattedDate(date, preformattedDate, hideYear) {
const day = date.getDate();
const month = MONTH_NAMES[date.getMonth()];
const year = date.getFullYear();
let hours = date.getHours();
let minutes = date.getMinutes();
const ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12 || 12; // Convert hours to 12-hour format
minutes = minutes < 10 ? `0${minutes}` : minutes; // Add leading zero to minutes
if (preformattedDate) {
return `${preformattedDate} at ${hours}:${minutes} ${ampm}`;
}
if (hideYear) {
return `${month} ${getOrdinalNum(day)}, at ${hours}:${minutes} ${ampm}`;
}
return `${month} ${getOrdinalNum(day)}, ${year} at ${hours}:${minutes} ${ampm}`;
}
// Validate the date parameter
function validateDateParam(dateParam) {
if (dateParam === undefined || dateParam === null) {
throw new Error("Invalid date parameter: dateParam cannot be empty. It must be a valid ISO date string or a Date object.");
}
if (typeof dateParam === 'string') {
const date = new Date(dateParam);
if (isNaN(date.getTime())) {
throw new Error("Invalid date parameter: dateParam is not a valid ISO date string.");
}
return date;
}
if (typeof dateParam === 'object' && dateParam instanceof Date) {
return dateParam;
}
throw new Error("Invalid date parameter: dateParam must be a valid ISO date string or a Date object.");
}
// Main function to calculate the "time ago" string
function timeAgo(dateParam) {
const date = validateDateParam(dateParam);
const now = new Date();
// Check if the date is in the future
if (date > now) {
throw new Error("Invalid date: The provided date is in the future.");
}
const DAY_IN_MS = 86400000; // 24 * 60 * 60 * 1000
const YEAR_IN_MS = 365.25 * DAY_IN_MS; // Account for leap years
const yesterday = new Date(now.getTime() - DAY_IN_MS);
const seconds = Math.round((now.getTime() - date.getTime()) / 1000);
const minutes = Math.round(seconds / 60);
const hours = Math.round(minutes / 60);
const days = Math.round(hours / 24);
const months = Math.round(days / 30.44); // More accurate month calculation
const years = Math.floor(days / 365.25); // More accurate year calculation
const isToday = now.toDateString() === date.toDateString();
const isYesterday = yesterday.toDateString() === date.toDateString();
// Specific check for exactly one year ago
const oneYearAgo = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());
if (date.toDateString() === oneYearAgo.toDateString()) {
return '1 year ago';
}
// Detailed logging for debugging
// console.log({
// seconds,
// minutes,
// hours,
// days,
// months,
// years,
// isToday,
// isYesterday,
// now,
// date
// });
switch (true) {
case (seconds < 2):
return 'now';
case (seconds < 60):
return `${seconds} seconds ago`;
case (seconds < 90):
return 'about a minute ago';
case (minutes < 60):
return `${minutes} minutes ago`;
case (hours === 1):
return '1 hour ago';
case (hours < 24):
return `${hours} hours ago`;
case (isToday):
return getFormattedDate(date, 'Today');
case (isYesterday):
return getFormattedDate(date, 'Yesterday');
case (days < 30):
return `${days} days ago`;
case (months === 1):
return '1 month ago';
case (months < 12):
return `${months} months ago`;
case (years === 1):
return '1 year ago';
case (years > 1):
return `${years} years ago`;
default:
return getFormattedDate(date);
}
}
return timeAgo(dateParam);
} catch (error) {
console.error("Error in showtimeago function:", error);
throw new Error(error.message);
}
}
// console.log(showtimeago("2024-07-18T17:12:00.000Z"));
// Example usage to test with current time
// const now = new Date();
// console.log("Current time:", now.toISOString());
// console.log("Result:", showtimeago(now));
// // Test with 5 seconds ago
// const fiveSecondsAgo = new Date(now.getTime() - 5000);
// console.log("5 seconds ago:", fiveSecondsAgo.toISOString());
// console.log("Result:", showtimeago(fiveSecondsAgo));
// // Test with 1 minute ago
// const oneMinuteAgo = new Date(now.getTime() - 60000);
// console.log("1 minute ago:", oneMinuteAgo.toISOString());
// console.log("Result:", showtimeago(oneMinuteAgo));
module.exports = showtimeago;