(date1: string, date2: string)
| 1126 | * Uses UTC anchoring for all date-only strings to ensure timezone-independent comparisons |
| 1127 | */ |
| 1128 | export function isBeforeDateTimeAware(date1: string, date2: string): boolean { |
| 1129 | try { |
| 1130 | // Step 1: Parse all dates to UTC anchors for consistency |
| 1131 | const d1UTC = parseDateToUTC(date1); |
| 1132 | const d2UTC = parseDateToUTC(date2); |
| 1133 | |
| 1134 | // Step 2: For datetime strings, add time component to UTC anchor |
| 1135 | let d1Final = d1UTC; |
| 1136 | let d2Final = d2UTC; |
| 1137 | |
| 1138 | if (hasTimeComponent(date1)) { |
| 1139 | // Extract time and apply it to UTC anchor |
| 1140 | const timeInfo = getTimePart(date1); |
| 1141 | if (timeInfo) { |
| 1142 | const [hours, minutes] = timeInfo.split(":").map(Number); |
| 1143 | d1Final = new Date(d1UTC); |
| 1144 | d1Final.setUTCHours(hours, minutes, 0, 0); |
| 1145 | } |
| 1146 | } |
| 1147 | |
| 1148 | if (hasTimeComponent(date2)) { |
| 1149 | // Extract time and apply it to UTC anchor |
| 1150 | const timeInfo = getTimePart(date2); |
| 1151 | if (timeInfo) { |
| 1152 | const [hours, minutes] = timeInfo.split(":").map(Number); |
| 1153 | d2Final = new Date(d2UTC); |
| 1154 | d2Final.setUTCHours(hours, minutes, 0, 0); |
| 1155 | } |
| 1156 | } |
| 1157 | |
| 1158 | // Step 3: Handle mixed case by treating date-only as end-of-day |
| 1159 | if (hasTimeComponent(date1) && !hasTimeComponent(date2)) { |
| 1160 | // date2 is date-only, treat as end of day for sorting |
| 1161 | d2Final = new Date(d2UTC); |
| 1162 | d2Final.setUTCHours(23, 59, 59, 999); |
| 1163 | } else if (!hasTimeComponent(date1) && hasTimeComponent(date2)) { |
| 1164 | // date1 is date-only, treat as end of day for sorting |
| 1165 | d1Final = new Date(d1UTC); |
| 1166 | d1Final.setUTCHours(23, 59, 59, 999); |
| 1167 | } |
| 1168 | |
| 1169 | // Step 4: Direct comparison with consistent UTC timestamps |
| 1170 | return d1Final.getTime() < d2Final.getTime(); |
| 1171 | } catch (error) { |
| 1172 | tasknotesLogger.error("Error comparing dates time-aware:", { |
| 1173 | category: "validation", |
| 1174 | operation: "comparing-dates-time-aware", |
| 1175 | details: { date1, date2 }, |
| 1176 | error: error, |
| 1177 | }); |
| 1178 | return false; |
| 1179 | } |
| 1180 | } |
| 1181 | |
| 1182 | /** |
| 1183 | * Check if a date/datetime is overdue (past current date/time) |
no test coverage detected