()
| 471 | }) |
| 472 | |
| 473 | function parseDateTime() { |
| 474 | const dateText = document.querySelector('.date-time h2').textContent.trim() // e.g., "APRIL 30TH, 2025" |
| 475 | const timeText = document.querySelector('.date-time h3').textContent.trim() // e.g., "ONLINE, 1:00 PM PT" |
| 476 | |
| 477 | // Remove ordinal indicators (st, nd, rd, th) and parse date |
| 478 | const cleanDateText = dateText.replace(/(ST|ND|RD|TH),/i, ',') |
| 479 | |
| 480 | // Create a more precise regex to match the date format |
| 481 | const dateTimeParts = cleanDateText.match(/^([A-Za-z]+)\s+(\d{1,2}),\s*(\d{4})$/i) |
| 482 | // Handle "ONLINE, " prefix in time |
| 483 | const timeParts = timeText |
| 484 | .replace(/^ONLINE,\s*/i, '') |
| 485 | .match(/^(\d{1,2}):(\d{2})\s*(AM|PM)\s*(PST|PDT|EST|EDT|CST|CDT|MST|MDT|PT)?$/i) |
| 486 | |
| 487 | if (!dateTimeParts || !timeParts) { |
| 488 | throw new Error('Invalid date/time format') |
| 489 | } |
| 490 | |
| 491 | const [, month, day, year] = dateTimeParts |
| 492 | const [, hours, minutes, ampm, timezone] = timeParts |
| 493 | |
| 494 | let hour24 = parseInt(hours) |
| 495 | |
| 496 | // Convert to 24-hour format |
| 497 | if (ampm.toUpperCase() === 'PM' && hour24 < 12) hour24 += 12 |
| 498 | if (ampm.toUpperCase() === 'AM' && hour24 === 12) hour24 = 0 |
| 499 | |
| 500 | // Create date in UTC |
| 501 | const date = new Date( |
| 502 | Date.UTC(parseInt(year), getMonthIndex(month), parseInt(day), hour24, parseInt(minutes), 0) |
| 503 | ) |
| 504 | |
| 505 | // Since the time is specified in PT (Pacific Time), adjust for PT (-7 hours from UTC during PDT) |
| 506 | date.setUTCHours(date.getUTCHours() - 7) |
| 507 | |
| 508 | if (isNaN(date.getTime())) { |
| 509 | throw new Error('Invalid date/time format') |
| 510 | } |
| 511 | |
| 512 | return date |
| 513 | } |
| 514 | |
| 515 | // Helper function to get month index (0-11) from month name |
| 516 | function getMonthIndex(month) { |
nothing calls this directly
no test coverage detected