Merge pull request #2555 from Succubyss/timestamp-hell Timestamp Fixes & Refactoring

de38b06eec719963a9538a45fbba088c0e418d86

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
2 files changed, +44 -36Ignore whitespace
public/scripts/RossAscends-mods.js+9 -12
@@ -157,18 +157,15 @@ export function shouldSendOnEnter() {
157//Does not break old characters/chats, as the code just uses whatever timestamp exists in the chat.157//Does not break old characters/chats, as the code just uses whatever timestamp exists in the chat.
158//New chats made with characters will use this new formatting.158//New chats made with characters will use this new formatting.
159export function humanizedDateTime() {159export function humanizedDateTime() {
160 let baseDate = new Date(Date.now());160 const now = new Date(Date.now());
161 let humanYear = baseDate.getFullYear();161 const dt = {
162 let humanMonth = baseDate.getMonth() + 1;162 year: now.getFullYear(), month: now.getMonth() + 1, day: now.getDate(),
163 let humanDate = baseDate.getDate();163 hour: now.getHours(), minute: now.getMinutes(), second: now.getSeconds(),
164 let humanHour = (baseDate.getHours() < 10 ? '0' : '') + baseDate.getHours();164 };
165 let humanMinute =165 for (const key in dt) {
166 (baseDate.getMinutes() < 10 ? '0' : '') + baseDate.getMinutes();166 dt[key] = dt[key].toString().padStart(2, '0');
167 let humanSecond =167 }
168 (baseDate.getSeconds() < 10 ? '0' : '') + baseDate.getSeconds();168 return `${dt.year}-${dt.month}-${dt.day}@${dt.hour}h${dt.minute}m${dt.second}s`;
169 let HumanizedDateTime =
170 humanYear + '-' + humanMonth + '-' + humanDate + '@' + humanHour + 'h' + humanMinute + 'm' + humanSecond + 's';
171 return HumanizedDateTime;
172}169}
173170
174//this is a common format version to display a timestamp on each chat message171//this is a common format version to display a timestamp on each chat message
public/scripts/utils.js+35 -24
@@ -722,43 +722,54 @@ export function timestampToMoment(timestamp) {
722 return moment;722 return moment;
723}723}
724724
725/**
726 * Parses a timestamp and returns a moment object representing the parsed date and time.
727 * @param {string|number} timestamp - The timestamp to parse. It can be a string or a number.
728 * @returns {moment.Moment} - A moment object representing the parsed date and time. If the timestamp is invalid, an invalid moment object is returned.
729 */
725function parseTimestamp(timestamp) {730function parseTimestamp(timestamp) {
726 if (!timestamp) {731 if (!timestamp) return moment.invalid();
727 return moment.invalid();
728 }
729732
730 // Unix time (legacy TAI / tags)733 // Unix time (legacy TAI / tags)
731 if (typeof timestamp === 'number' || /^\d+$/.test(timestamp)) {734 if (typeof timestamp === 'number' || /^\d+$/.test(timestamp)) {
732 if (isNaN(timestamp) || !isFinite(timestamp) || timestamp < 0) {735 const number = Number(timestamp);
733 return moment.invalid();736 if (isNaN(number)) return moment.invalid();
734 }737 if (!isFinite(number)) return moment.invalid();
735 return moment(Number(timestamp));738 if (number < 0) return moment.invalid();
739 return moment(number);
736 }740 }
737741
738 // ST "humanized" format pattern742 let dtFmt = [];
739 const pattern1 = /(\d{4})-(\d{1,2})-(\d{1,2}) @(\d{1,2})h (\d{1,2})m (\d{1,2})s (\d{1,3})ms/;
740 const replacement1 = (match, year, month, day, hour, minute, second, millisecond) => {
741 return `${year.padStart(4, '0')}-${month.padStart(2, '0')}-${day.padStart(2, '0')}T${hour.padStart(2, '0')}:${minute.padStart(2, '0')}:${second.padStart(2, '0')}.${millisecond.padStart(3, '0')}Z`;
742 };
743 const isoTimestamp1 = timestamp.replace(pattern1, replacement1);
744 if (moment(isoTimestamp1).isValid()) {
745 return moment(isoTimestamp1);
746 }
747743
748 // New format pattern: "June 19, 2023 4:13pm"744 // meridiem-based format
749 const pattern2 = /(\w+)\s(\d{1,2}),\s(\d{4})\s(\d{1,2}):(\d{1,2})(am|pm)/i;745 const convertFromMeridiemBased = (_, month, day, year, hour, minute, meridiem) => {
750 const replacement2 = (match, month, day, year, hour, minute, meridiem) => {
751 const monthNum = moment().month(month).format('MM');746 const monthNum = moment().month(month).format('MM');
752 const hour24 = meridiem.toLowerCase() === 'pm' ? (parseInt(hour, 10) % 12) + 12 : parseInt(hour, 10) % 12;747 const hour24 = meridiem.toLowerCase() === 'pm' ? (parseInt(hour, 10) % 12) + 12 : parseInt(hour, 10) % 12;
753 return `${year}-${monthNum}-${day.padStart(2, '0')}T${hour24.toString().padStart(2, '0')}:${minute.padStart(2, '0')}:00`;748 return `${year}-${monthNum}-${day.padStart(2, '0')}T${hour24.toString().padStart(2, '0')}:${minute.padStart(2, '0')}:00`;
754 };749 };
755 const isoTimestamp2 = timestamp.replace(pattern2, replacement2);750 // June 19, 2023 2:20pm
756 if (moment(isoTimestamp2).isValid()) {751 dtFmt.push({ callback: convertFromMeridiemBased, pattern: /(\w+)\s(\d{1,2}),\s(\d{4})\s(\d{1,2}):(\d{1,2})(am|pm)/i });
757 return moment(isoTimestamp2);752
753 // ST "humanized" format patterns
754 const convertFromHumanized = (_, year, month, day, hour, min, sec, ms) => {
755 ms = typeof ms !== 'undefined' ? `.${ms.padStart(3, '0')}` : '';
756 return `${year.padStart(4, '0')}-${month.padStart(2, '0')}-${day.padStart(2, '0')}T${hour.padStart(2, '0')}:${min.padStart(2, '0')}:${sec.padStart(2, '0')}${ms}Z`;
757 };
758 // 2024-7-12@01h31m37s
759 dtFmt.push({ callback: convertFromHumanized, pattern: /(\d{4})-(\d{1,2})-(\d{1,2})@(\d{1,2})h(\d{1,2})m(\d{1,2})s/ });
760 // 2024-6-5 @14h 56m 50s 682ms
761 dtFmt.push({ callback: convertFromHumanized, pattern: /(\d{4})-(\d{1,2})-(\d{1,2}) @(\d{1,2})h (\d{1,2})m (\d{1,2})s (\d{1,3})ms/ });
762
763 let iso8601;
764 for (const x of dtFmt) {
765 let rgxMatch = timestamp.match(x.pattern);
766 if (!rgxMatch) continue;
767 iso8601 = x.callback(...rgxMatch);
768 break;
758 }769 }
759770
760 // If none of the patterns match, return an invalid moment object771 // If one of the patterns matched, return a valid moment object, otherwise return an invalid moment object
761 return moment.invalid();772 return iso8601 ? moment(iso8601) : moment.invalid();
762}773}
763774
764/**775/**