@@ -44,4 +44,79 @@ export function parseTaskDate(dateStr: string): number {
4444 if ( ! dateStr ) return null ;
4545 const fixed = dateStr . replace ( / ( \. \d { 3 } ) \d + / , '$1' ) ;
4646 return new Date ( fixed + 'Z' ) . getTime ( ) ;
47+ }
48+
49+ export function formatDisplayTimestamp ( createdAt : string ) : string {
50+ if ( ! createdAt ) return "<unknown>" ;
51+ const date = parseUTCToLocal ( createdAt ) ;
52+ const now = new Date ( ) ;
53+
54+ const isSameDay = ( d1 : Date , d2 : Date ) =>
55+ d1 . getFullYear ( ) === d2 . getFullYear ( ) &&
56+ d1 . getMonth ( ) === d2 . getMonth ( ) &&
57+ d1 . getDate ( ) === d2 . getDate ( ) ;
58+
59+ if ( isSameDay ( date , now ) ) {
60+ const hours = date . getHours ( ) . toString ( ) . padStart ( 2 , "0" ) ;
61+ const minutes = date . getMinutes ( ) . toString ( ) . padStart ( 2 , "0" ) ;
62+ return `${ hours } :${ minutes } ` ;
63+ }
64+
65+ const yesterday = new Date ( ) ;
66+ yesterday . setDate ( now . getDate ( ) - 1 ) ;
67+ if ( isSameDay ( date , yesterday ) ) {
68+ return "Yesterday" ;
69+ }
70+
71+ const weekdays = [ "Sun" , "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" ] ;
72+ const weekday = weekdays [ date . getDay ( ) ] ;
73+ const day = date . getDate ( ) . toString ( ) . padStart ( 2 , "0" ) ;
74+ const month = ( date . getMonth ( ) + 1 ) . toString ( ) . padStart ( 2 , "0" ) ;
75+ const year = date . getFullYear ( ) . toString ( ) . slice ( - 2 ) ;
76+
77+ return `${ weekday } , ${ day } .${ month } .${ year } ` ;
78+ }
79+
80+ export function parseUTCToLocal ( dateString : string ) : Date {
81+ const d = new Date ( dateString ) ;
82+
83+ if ( ! / [ z Z ] | [ + - ] \d { 2 } : ? \d { 2 } $ / . test ( dateString ) ) {
84+ const parts = dateString . split ( / [ - T : ] / ) . map ( Number ) ;
85+ return new Date ( Date . UTC ( parts [ 0 ] , parts [ 1 ] - 1 , parts [ 2 ] , parts [ 3 ] , parts [ 4 ] || 0 , parts [ 5 ] || 0 ) ) ;
86+ }
87+
88+ return d ;
89+ }
90+
91+ export function formatDisplayTimestampFull ( createdAt : string ) : string {
92+ const date = parseUTCToLocal ( createdAt ) ;
93+ const now = new Date ( ) ;
94+
95+ const diffMs = now . getTime ( ) - date . getTime ( ) ;
96+ const diffMinutes = Math . floor ( diffMs / ( 1000 * 60 ) ) ;
97+ const diffHours = Math . floor ( diffMinutes / 60 ) ;
98+ const diffDays = Math . floor ( diffHours / 24 ) ;
99+
100+ const weekdays = [ "Sun" , "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" ] ;
101+ const weekday = weekdays [ date . getDay ( ) ] ;
102+ const day = date . getDate ( ) . toString ( ) . padStart ( 2 , "0" ) ;
103+ const month = ( date . getMonth ( ) + 1 ) . toString ( ) . padStart ( 2 , "0" ) ;
104+ const year = date . getFullYear ( ) . toString ( ) . padStart ( 4 , "0" ) ;
105+ const hours = date . getHours ( ) . toString ( ) . padStart ( 2 , "0" ) ;
106+ const minutes = date . getMinutes ( ) . toString ( ) . padStart ( 2 , "0" ) ;
107+
108+ let relative = "" ;
109+ if ( diffMinutes < 1 ) {
110+ relative = "(just now)" ;
111+ } else if ( diffMinutes < 60 ) {
112+ relative = `(${ diffMinutes } minute${ diffMinutes !== 1 ? "s" : "" } ago)` ;
113+ } else if ( diffHours < 24 ) {
114+ relative = `(${ diffHours } hour${ diffHours !== 1 ? "s" : "" } ago)` ;
115+ } else if ( diffDays === 1 ) {
116+ relative = `(yesterday)` ;
117+ } else {
118+ relative = `(${ diffDays } day${ diffDays !== 1 ? "s" : "" } ago)` ;
119+ }
120+
121+ return `${ weekday } , ${ day } .${ month } .${ year } ${ hours } :${ minutes } ${ relative } ` ;
47122}
0 commit comments