human (Dec 9, 2024, 10:21 AM)
A timezone meeting planner - it lets you select two timezones using a select datalist against Intl.supportedValuesOf('timeZone') and as soon as you have selected the two shows you a timezone comparison view that looks a bit like this
It persists the selected timezones in the #fragment URL
assistant (Dec 9, 2024, 10:21 AM)
I'll help you create a timezone meeting planner with vanilla JavaScript and HTML. I'll use modern browser APIs and maintain the design pattern you've shown.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Timezone Meeting Planner</title>
<style>
* {
box-sizing: border-box;
}
body {
font-family: Helvetica, Arial, sans-serif;
margin: 0;
padding: 20px;
line-height: 1.4;
}
.timezone-selectors {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 30px;
}
.timezone-input {
font-size: 16px;
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.comparison-table {
width: 100%;
border-collapse: collapse;
}
.comparison-table th {
text-align: left;
padding: 12px;
background: #f0f0f0;
border: 1px solid #ddd;
}
.comparison-table td {
padding: 12px;
border: 1px solid #ddd;
}
.comparison-table tr:nth-child(even) {
background: #f8f8f8;
}
.timezone-label {
color: #4a5568;
font-size: 1.2em;
margin-bottom: 8px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="timezone-selectors">
<div>
<div class="timezone-label">First Timezone</div>
<input
type="text"
id="timezone1"
class="timezone-input"
list="timezone-list"
placeholder="Select timezone...">
</div>
<div>
<div class="timezone-label">Second Timezone</div>
<input
type="text"
id="timezone2"
class="timezone-input"
list="timezone-list"
placeholder="Select timezone...">
</div>
</div>
<datalist id="timezone-list"></datalist>
<table class="comparison-table" id="comparison-table">
<thead>
<tr>
<th>UTC-time</th>
<th id="tz1-header">First Location</th>
<th id="tz2-header">Second Location</th>
</tr>
</thead>
<tbody id="comparison-body">
</tbody>
</table>
<script type="module">
const timezones = Intl.supportedValuesOf('timeZone')
const tzDatalist = document.getElementById('timezone-list')
const tz1Input = document.getElementById('timezone1')
const tz2Input = document.getElementById('timezone2')
const tz1Header = document.getElementById('tz1-header')
const tz2Header = document.getElementById('tz2-header')
const comparisonBody = document.getElementById('comparison-body')
// Populate datalist with all supported timezones
timezones.forEach(tz => {
const option = document.createElement('option')
option.value = tz
tzDatalist.appendChild(option)
})
function updateURL(tz1, tz2) {
const hash = `#${encodeURIComponent(tz1)},${encodeURIComponent(tz2)}`
window.history.replaceState(null, '', hash)
}
function loadFromURL() {
const hash = window.location.hash.slice(1)
if (hash) {
const [tz1, tz2] = hash.split(',').map(decodeURIComponent)
if (timezones.includes(tz1) && timezones.includes(tz2)) {
tz1Input.value = tz1
tz2Input.value = tz2
updateComparison()
}
}
}
function formatTime(date, timezone) {
return new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: true,
timeZone: timezone,
weekday: 'short'
}).format(date)
}
function updateComparison() {
const tz1 = tz1Input.value
const tz2 = tz2Input.value
if (!timezones.includes(tz1) || !timezones.includes(tz2)) return
tz1Header.textContent = tz1.split('/').pop().replace(/_/g, ' ')
tz2Header.textContent = tz2.split('/').pop().replace(/_/g, ' ')
updateURL(tz1, tz2)
// Clear existing rows
comparisonBody.innerHTML = ''
// Create 24 hourly comparisons
const now = new Date()
now.setMinutes(0, 0, 0)
for (let i = 0; i < 24; i++) {
const row = document.createElement('tr')
const utcCell = document.createElement('td')
utcCell.textContent = now.toISOString().replace('T', ' at ').slice(0, -5)
const tz1Cell = document.createElement('td')
tz1Cell.textContent = formatTime(now, tz1)
const tz2Cell = document.createElement('td')
tz2Cell.textContent = formatTime(now, tz2)
row.appendChild(utcCell)
row.appendChild(tz1Cell)
row.appendChild(tz2Cell)
comparisonBody.appendChild(row)
now.setHours(now.getHours() + 1)
}
}
tz1Input.addEventListener('change', updateComparison)
tz2Input.addEventListener('change', updateComparison)
// Load initial state from URL
loadFromURL()
</script>
</body>
</html>
I've created a timezone meeting planner with these key features:
- Timezone selection using datalist populated with
Intl.supportedValuesOf('timeZone')
- URL persistence using the hash fragment
- 24-hour comparison view showing times in both selected zones
- Clean, responsive design with proper font sizing and styling
- Proper error handling for invalid timezones
The interface automatically updates when you select timezones and preserves your selections in the URL. The comparison table shows a full 24-hour view with proper formatting for both timezones.
Try selecting two different timezones from the dropdown lists. The URL will update automatically, and you can share it with others to show the same comparison.
Would you like me to add any additional features or make any adjustments to the styling?