@@ -35,3 +35,40 @@ export function formatDate(unixTimestamp: number, withTime = false): string {
3535 : { month : "long" , day : "2-digit" , year : "numeric" } ;
3636 return date . toLocaleDateString ( "en-US" , options ) ;
3737}
38+
39+ /**
40+ * Calculates the time left until a specified date and formats it.
41+ *
42+ * @param {string } isoString - An ISO 8601 formatted date string (e.g., "2024-10-29T09:52:08.580Z").
43+ * @returns {string } A human-readable string indicating the time left until the specified date.
44+ * @example
45+ * console.log(timeLeftUntil("2024-10-29T09:52:08.580Z"));
46+ * // Outputs: "in x secs", "in x mins", "in x hrs", or "after October 29, 2024"
47+ */
48+ export function timeLeftUntil ( isoString : string ) : string {
49+ const targetDate = new Date ( isoString ) ;
50+ const now = new Date ( ) ;
51+ const timeDifference = targetDate . getTime ( ) - now . getTime ( ) ;
52+
53+ if ( timeDifference <= 0 ) {
54+ return "The date has already passed." ;
55+ }
56+
57+ const secondsLeft = Math . floor ( timeDifference / 1000 ) ;
58+ const minutesLeft = Math . floor ( secondsLeft / 60 ) ;
59+ const hoursLeft = Math . floor ( minutesLeft / 60 ) ;
60+ const daysLeft = Math . floor ( hoursLeft / 24 ) ;
61+
62+ if ( secondsLeft < 60 ) {
63+ return `in ${ secondsLeft } sec${ secondsLeft > 1 ? "s" : "" } ` ;
64+ } else if ( minutesLeft < 60 ) {
65+ return `in ${ minutesLeft } min${ minutesLeft > 1 ? "s" : "" } ` ;
66+ } else if ( hoursLeft < 24 ) {
67+ return `in ${ hoursLeft } hr${ hoursLeft > 1 ? "s" : "" } ` ;
68+ } else if ( daysLeft < 2 ) {
69+ return `in ${ daysLeft } day${ daysLeft > 1 ? "s" : "" } ` ;
70+ } else {
71+ const options : Intl . DateTimeFormatOptions = { year : "numeric" , month : "long" , day : "numeric" } ;
72+ return `after ${ targetDate . toLocaleDateString ( "en-US" , options ) } ` ;
73+ }
74+ }
0 commit comments