| ← Back to Timezone Handling | Back to Table of Contents |
10.3.1 KMP_Timezone Utility API Reference
Overview
The KMP_Timezone utility provides comprehensive client-side timezone handling for the KMP application. It automatically initializes on page load and is available globally as window.KMP_Timezone.
Location: app/assets/js/timezone-utils.js
Key Features:
- Automatic timezone detection from browser
- UTC to local timezone conversion for display
- Local to UTC conversion for form submission
- HTML5 datetime-local input support
- Automatic initialization of elements with
data-utc-valueattributes
Core API Methods
Timezone Detection
detectTimezone(): string
Detects the user’s timezone from their browser using the Intl.DateTimeFormat API.
Returns: IANA timezone identifier (e.g., "America/Chicago")
Example:
const userTz = KMP_Timezone.detectTimezone();
// Returns: "America/Chicago"
Error Handling: Falls back to "UTC" if detection fails, with warning logged to console.
getTimezone(element: HTMLElement): string
Retrieves timezone from element’s data-timezone attribute or detects from browser.
Parameters:
element(HTMLElement): Element with optionaldata-timezoneattribute
Returns: Timezone identifier string
Example:
const tz = KMP_Timezone.getTimezone(document.getElementById('myInput'));
// Returns timezone from element or detected timezone
Formatting Methods
formatDateTime(utcDateTime, timezone, options): string
Converts UTC datetime to local timezone and formats for display.
Parameters:
-
utcDateTime(stringDate): UTC datetime string or Date object timezone(string, optional): Target timezone. Defaults to detected timezoneoptions(object, optional):Intl.DateTimeFormatoptions
Returns: Formatted datetime string
Default Options:
{
timeZone: timezone,
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
hour12: true
}
Examples:
// Basic usage
const utcString = "2025-03-15T14:30:00Z";
const displayed = KMP_Timezone.formatDateTime(utcString, "America/Chicago");
// Output: "3/15/2025, 9:30:00 AM"
// Custom format - full day name and short time
const custom = KMP_Timezone.formatDateTime(utcString, "America/Chicago", {
dateStyle: 'full',
timeStyle: 'short'
});
// Output: "Saturday, March 15, 2025 at 9:30 AM"
// Two-digit month/day
const twoDigit = KMP_Timezone.formatDateTime(utcString, "America/Chicago", {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false
});
// Output: "03/15/2025, 09:30"
Error Handling: Returns empty string if invalid datetime or timezone, logs error to console.
formatDate(utcDateTime, timezone, options): string
Formats date only (no time component) in user’s timezone.
Parameters:
-
utcDateTime(stringDate): UTC datetime timezone(string, optional): Target timezoneoptions(object, optional):Intl.DateTimeFormatoptions
Returns: Formatted date string
Default Options:
{
timeZone: timezone,
year: 'numeric',
month: 'long',
day: 'numeric'
}
Examples:
const date = "2025-03-15T14:30:00Z";
// Default format
KMP_Timezone.formatDate(date, "America/Chicago");
// Output: "March 15, 2025"
// Short month abbreviation
KMP_Timezone.formatDate(date, "America/Chicago", {
year: 'numeric',
month: 'short',
day: 'numeric'
});
// Output: "Mar 15, 2025"
formatTime(utcDateTime, timezone, options): string
Formats time only (no date component) in user’s timezone.
Parameters:
-
utcDateTime(stringDate): UTC datetime timezone(string, optional): Target timezoneoptions(object, optional):Intl.DateTimeFormatoptions
Returns: Formatted time string
Default Options:
{
timeZone: timezone,
hour: 'numeric',
minute: '2-digit',
hour12: true
}
Examples:
const datetime = "2025-03-15T14:30:00Z";
// 12-hour format (default)
KMP_Timezone.formatTime(datetime, "America/Chicago");
// Output: "9:30 AM"
// 24-hour format
KMP_Timezone.formatTime(datetime, "America/Chicago", {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
// Output: "09:30:00"
// With seconds
KMP_Timezone.formatTime(datetime, "America/Chicago", {
hour: 'numeric',
minute: '2-digit',
second: '2-digit',
hour12: true
});
// Output: "9:30:00 AM"
DateTime Input Methods
These methods handle conversion between UTC and datetime-local HTML input format (YYYY-MM-DDTHH:mm).
toLocalInput(utcDateTime, timezone): string
Converts UTC datetime to HTML5 datetime-local format in user’s timezone.
Parameters:
-
utcDateTime(stringDate): UTC datetime timezone(string, optional): Target timezone
Returns: String in format YYYY-MM-DDTHH:mm representing local time
Use Case: Populate datetime-local input elements with values converted to user’s timezone
Examples:
const utcDate = "2025-03-15T14:30:00Z";
// Convert to local time for input
const inputValue = KMP_Timezone.toLocalInput(utcDate, "America/Chicago");
// Output: "2025-03-15T09:30"
// Can be set directly on input
document.getElementById('startDate').value = inputValue;
// Empty input if no datetime provided
const empty = KMP_Timezone.toLocalInput(null, "America/Chicago");
// Output: ""
Technical Note: Uses Intl.DateTimeFormat.formatToParts() to reliably extract date and time components in the target timezone, accounting for DST transitions.
toUTC(localDateTime, timezone): string
Converts local datetime-local input value (user’s timezone) to ISO 8601 UTC format.
Parameters:
localDateTime(string): Datetime inYYYY-MM-DDTHH:mmformat (local time) orYYYY-MM-DD HH:mm:sstimezone(string, optional): Source timezone
Returns: ISO 8601 UTC datetime string (e.g., "2025-03-15T14:30:00.000Z")
Use Case: Convert user input from datetime-local field to UTC for server storage
Examples:
// Standard format from datetime-local input
const localInput = "2025-03-15T09:30";
const utcValue = KMP_Timezone.toUTC(localInput, "America/Chicago");
// Output: "2025-03-15T14:30:00.000Z"
// Alternative format with seconds
const withSeconds = KMP_Timezone.toUTC("2025-03-15 09:30:00", "America/Chicago");
// Output: "2025-03-15T14:30:00.000Z"
// Empty returns empty string
const empty = KMP_Timezone.toUTC("", "America/Chicago");
// Output: ""
Error Handling: Returns empty string and logs error if format is invalid or timezone unsupported.
getTimezoneOffset(timezone, date): number
Calculates the timezone offset in minutes for a specific timezone and date.
Parameters:
timezone(string): IANA timezone identifierdate(Date, optional): Date for offset calculation (default: current date). Important for DST handling.
Returns: Offset in minutes (positive for east of UTC, negative for west)
Use Case: Advanced use cases where you need the raw offset value
Examples:
// Get current offset (handles DST automatically)
const offset = KMP_Timezone.getTimezoneOffset("America/Chicago");
// Output: -300 (UTC-5, during CDT) or -360 (UTC-6, during CST)
// Get offset for specific date (useful for DST handling)
const winterDate = new Date("2025-01-15");
const winterOffset = KMP_Timezone.getTimezoneOffset("America/Chicago", winterDate);
// Output: -360 (CST, no DST)
const summerDate = new Date("2025-07-15");
const summerOffset = KMP_Timezone.getTimezoneOffset("America/Chicago", summerDate);
// Output: -300 (CDT, with DST)
// Positive offset (east of UTC)
const tokyoOffset = KMP_Timezone.getTimezoneOffset("Asia/Tokyo");
// Output: 540 (UTC+9)
getAbbreviation(timezone, date): string
Gets the timezone abbreviation for display (e.g., CDT, EST, PST).
Parameters:
timezone(string, optional): Timezone identifier. Defaults to detected timezone.date(Date, optional): Date for abbreviation calculation (default: now). Important for DST abbreviations.
Returns: Timezone abbreviation string
Use Case: Display timezone abbreviation in UI (e.g., “9:00 AM CDT”)
Examples:
// Current date (handles DST automatically)
const abbr = KMP_Timezone.getAbbreviation("America/Chicago");
// Output: "CDT" or "CST" depending on current date
// Specific date (winter = CST, summer = CDT)
const winterAbbr = KMP_Timezone.getAbbreviation("America/Chicago", new Date("2025-01-15"));
// Output: "CST"
const summerAbbr = KMP_Timezone.getAbbreviation("America/Chicago", new Date("2025-07-15"));
// Output: "CDT"
// Default (detected) timezone
const defaultAbbr = KMP_Timezone.getAbbreviation();
// Output: User's local timezone abbreviation
Initialization Methods
initializeDatetimeInputs(container): void
Automatically converts all datetime-local inputs with data-utc-value attributes to local time.
Parameters:
container(HTMLElement, optional): Container to search in. Defaults todocument.
Returns: None (modifies DOM in place)
Use Case: Auto-populate datetime-local inputs with UTC values converted to user’s timezone
Automatic Initialization: This method is automatically called on page load for the entire document.
Examples:
<!-- HTML: datetime-local input with UTC value -->
<input type="datetime-local"
name="start_date"
data-timezone="America/Chicago"
data-utc-value="2025-03-15T14:30:00Z"
class="form-control">
// Automatic on page load - no code needed!
// Input value becomes: "2025-03-15T09:30"
// Manual initialization for dynamically-added content
const modal = document.getElementById('myModal');
KMP_Timezone.initializeDatetimeInputs(modal);
// Or for entire document
KMP_Timezone.initializeDatetimeInputs();
// Or for specific form section
const form = document.getElementById('myForm');
KMP_Timezone.initializeDatetimeInputs(form);
Behavior:
- Finds all
<input type="datetime-local">elements withdata-utc-valueattribute - Converts UTC value to local time using element’s timezone
- Sets input
valueto converted local time - Does nothing if
data-utc-valueis missing or empty
convertFormDatetimesToUTC(form, timezone): void
Converts all datetime-local inputs in a form back to UTC before submission.
Parameters:
form(HTMLFormElement): Form element to processtimezone(string, optional): Source timezone. Defaults to detected timezone.
Returns: None (modifies form for submission)
Use Case: Ensure all datetime inputs are submitted as UTC values to server
Behavior:
- Scans form for all
<input type="datetime-local">elements - Converts each value from local time to UTC
- Creates hidden inputs with UTC values for server submission
- Disables original inputs to prevent duplicate data submission
- Stores original value in
data-original-valuefor reference - On conversion error, sets
data-conversion-error="true"and leaves original enabled
Examples:
<!-- HTML: Form with datetime inputs -->
<form id="myForm">
<input type="datetime-local" name="start_date" value="2025-03-15T09:30">
<input type="datetime-local" name="end_date" value="2025-03-15T14:30">
<button type="submit">Save</button>
</form>
// JavaScript: Convert on form submit
document.getElementById('myForm').addEventListener('submit', function(e) {
const timezone = KMP_Timezone.detectTimezone();
// Convert all datetime-local inputs to UTC
KMP_Timezone.convertFormDatetimesToUTC(this, timezone);
// Form now ready for submission - hidden inputs contain UTC values
// Original inputs are disabled
// Submit the form
this.submit();
});
Form Structure After Conversion:
<!-- After conversion, form contains: -->
<input type="datetime-local" name="start_date" value="2025-03-15T09:30" disabled>
<input type="hidden" name="start_date" value="2025-03-15T14:30:00.000Z">
<input type="datetime-local" name="end_date" value="2025-03-15T14:30" disabled>
<input type="hidden" name="end_date" value="2025-03-15T19:30:00.000Z">
Error Handling: If conversion fails for an input:
- Original input remains enabled
data-conversion-error="true"attribute is set- Error message logged to console
- Form can still be submitted (with local time instead of UTC)
Integration with Stimulus Controllers
Working with timezone-input-controller.js
The timezone-input-controller.js Stimulus controller automatically handles timezone conversion for forms:
<form data-controller="timezone-input">
<input type="datetime-local"
name="start_date"
data-utc-value="2025-03-15T14:30:00Z"
class="form-control">
<button type="submit">Save</button>
</form>
The controller automatically:
- Initializes all inputs on connect
- Converts inputs to UTC on form submission
- Handles error states gracefully
Common Usage Patterns
Pattern 1: Display UTC Datetime in User’s Timezone
// Server sends UTC datetime
const utcDateTime = "2025-03-15T14:30:00Z";
const timezone = "America/Chicago";
// Display to user
const display = KMP_Timezone.formatDateTime(utcDateTime, timezone);
// "3/15/2025, 9:30:00 AM"
document.getElementById('eventTime').textContent = display;
Pattern 2: Populate Form Input with UTC Value
<input type="datetime-local"
name="event_start"
data-timezone="America/Chicago"
data-utc-value="2025-03-15T14:30:00Z">
Automatically becomes: value="2025-03-15T09:30"
Pattern 3: Convert Form Input to UTC on Submit
form.addEventListener('submit', function(e) {
KMP_Timezone.convertFormDatetimesToUTC(this);
});
Submission sends UTC values to server.
Pattern 4: Get Timezone Abbreviation for Display
const datetime = "2025-03-15T14:30:00Z";
const tz = "America/Chicago";
const time = KMP_Timezone.formatTime(datetime, tz);
const abbr = KMP_Timezone.getAbbreviation(tz, new Date(datetime));
document.getElementById('time').textContent = `${time} ${abbr}`;
// "9:30 AM CDT"
Pattern 5: Smart Multi-Timezone Display
function displayInMultipleTimezones(utcDateTime) {
const timezones = ["America/Chicago", "America/New_York", "UTC"];
timezones.forEach(tz => {
const formatted = KMP_Timezone.formatDateTime(utcDateTime, tz);
const abbr = KMP_Timezone.getAbbreviation(tz, new Date(utcDateTime));
console.log(`${tz}: ${formatted} ${abbr}`);
});
}
// Output:
// America/Chicago: 3/15/2025, 9:30:00 AM CDT
// America/New_York: 3/15/2025, 10:30:00 AM EDT
// UTC: 3/15/2025, 2:30:00 PM UTC
Important Notes
DST Handling
The Intl.DateTimeFormat API automatically handles Daylight Saving Time:
// Winter date (CST = UTC-6)
const winterDate = "2025-01-15T14:30:00Z";
KMP_Timezone.formatDateTime(winterDate, "America/Chicago");
// Output: "1/15/2025, 8:30:00 AM" (14:30 UTC - 6 hours = 8:30 CST)
// Summer date (CDT = UTC-5)
const summerDate = "2025-07-15T14:30:00Z";
KMP_Timezone.formatDateTime(summerDate, "America/Chicago");
// Output: "7/15/2025, 9:30:00 AM" (14:30 UTC - 5 hours = 9:30 CDT)
Null/Empty Value Handling
All methods return empty strings for null, undefined, or invalid inputs:
KMP_Timezone.formatDateTime(null, "America/Chicago"); // ""
KMP_Timezone.formatDateTime(undefined, "America/Chicago"); // ""
KMP_Timezone.formatDateTime("", "America/Chicago"); // ""
KMP_Timezone.toLocalInput("invalid", "America/Chicago"); // ""
Timezone Validation
Use valid IANA timezone identifiers. Examples:
- US:
America/Chicago,America/New_York,America/Denver,America/Los_Angeles - UTC:
UTC - Europe:
Europe/London,Europe/Paris,Europe/Berlin - Asia:
Asia/Tokyo,Asia/Shanghai,Asia/Kolkata
Invalid timezones will cause the Intl API to throw, which is caught and logged.
Browser Compatibility
The KMP_Timezone utility uses the Intl.DateTimeFormat API which is supported in:
- Chrome 24+
- Firefox 29+
- Safari 11+
- Edge 12+
- All modern browsers
For older browsers, the utility falls back to Date.toLocaleString() with reduced functionality.
See Also
- Timezone Handling Guide - Complete timezone system documentation
- PHP TimezoneHelper - Server-side timezone utilities
- timezone-input-controller.js - Stimulus integration
| ← Back to Timezone Handling | Back to Table of Contents |