Skip to content

Instantly share code, notes, and snippets.

@malko
Created March 24, 2025 14:14
Show Gist options
  • Save malko/4f4e6e8891148a0c48decc1052def7ba to your computer and use it in GitHub Desktop.
Save malko/4f4e6e8891148a0c48decc1052def7ba to your computer and use it in GitHub Desktop.
initDateTimeWithTimezone
/**
* Return a date object with the specified date and timezone respecting DST
* @param {string} dateStr - Date string in 'YYYY-MM-DD' or 'YYYY-MM-DD[T| ]HH:MM:SS' format
* @param {string} timezone - IANA timezone string (e.g., 'Europe/Paris')
* @returns {Date} - Date object adjusted for the specified timezone
*/
function initDateTimeWithTimezone(dateStr, timezone) {
let year, month, day, hours = '00', minutes = '00', seconds = '00';
dateStr = dateStr.trim();
// Check if time is included in the date string
if (dateStr.includes('T') || dateStr.includes(' ')) {
// Parse date with time (YYYY-MM-DDT00:00:00 or YYYY-MM-DD 00:00:00)
const parts = dateStr.replace('T', ' ').split(' ');
// Parse date components
[year, month, day] = parts[0].split('-');
// Parse time components if provided
if (parts[1]) {
const timeParts = parts[1].split(':');
hours = timeParts[0] || '00';
minutes = timeParts[1] || '00';
seconds = timeParts[2] || '00';
}
} else {
// Parse date only (YYYY-MM-DD)
[year, month, day] = dateStr.split('-');
}
// Create ISO string like '2025-03-30T00:00:00' in target timezone format
const targetDateISO = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;
// Use the date with timezone string format
const targetTZDate = new Date(`${targetDateISO}Z`);
// Create a formatter that will give us the UTC offset for this specific date and timezone
const options = {
timeZone: timezone,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
timeZoneName: 'short'
};
const formatter = new Intl.DateTimeFormat('en-US', options);
const dateInTZ = formatter.format(targetTZDate);
// Extract timezone offset from the formatted string (like "03/30/2025, 00:00:00 GMT+2")
const tzOffsetMatch = dateInTZ.match(/GMT([+-])(\d+)/);
console.log('offset', tzOffsetMatch[0]);
if (tzOffsetMatch) {
const sign = tzOffsetMatch[1] === '+' ? -1 : 1; // If GMT+2, we need to subtract 2 hours from UTC
const hours = parseInt(tzOffsetMatch[2], 10);
// Calculate the UTC time by adjusting for the timezone offset
// For midnight in Paris (GMT+2), the UTC time would be 10 PM (22:00) the previous day
const offsetMillis = sign * hours * 60 * 60 * 1000;
return new Date(targetTZDate.getTime() + offsetMillis);
}
// Fallback if we couldn't extract the timezone offset
return targetTZDate;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment