76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
export interface FormatUnixTimestampResult {
|
|
time: string;
|
|
timezone: string;
|
|
}
|
|
|
|
|
|
export const formatUnixTimestamp = (
|
|
timestamp: number,
|
|
locale?: string | string[],
|
|
options?: Intl.DateTimeFormatOptions
|
|
): FormatUnixTimestampResult => {
|
|
const milliseconds = timestamp * 1000;
|
|
|
|
const date = new Date(milliseconds);
|
|
|
|
const formattedTime = date.toLocaleString(locale, options);
|
|
|
|
// Calculate UTC offset in hours
|
|
// getTimezoneOffset() returns offset in minutes (negative if ahead of UTC)
|
|
const offsetMinutes = date.getTimezoneOffset();
|
|
const offsetHours = -offsetMinutes / 60;
|
|
const offsetSign = offsetHours >= 0 ? '+' : '-';
|
|
const offsetAbs = Math.abs(offsetHours);
|
|
|
|
// Format as UTC +2 or UTC -5 (with space and sign)
|
|
let timezone: string;
|
|
if (options?.timeZone) {
|
|
// If a specific timezone is requested, calculate offset for that timezone
|
|
try {
|
|
// Get the offset for the specified timezone
|
|
const formatter = new Intl.DateTimeFormat('en', {
|
|
timeZone: options.timeZone,
|
|
timeZoneName: 'shortOffset'
|
|
});
|
|
const parts = formatter.formatToParts(date);
|
|
const offsetPart = parts.find(part => part.type === 'timeZoneName');
|
|
|
|
if (offsetPart?.value) {
|
|
// Format like "GMT+2" or "GMT-5"
|
|
timezone = offsetPart.value.replace('GMT', 'UTC');
|
|
} else {
|
|
// Fallback: calculate offset manually
|
|
const utcTime = date.getTime() + (date.getTimezoneOffset() * 60000);
|
|
const tzDate = new Date(utcTime);
|
|
const tzFormatter = new Intl.DateTimeFormat('en', {
|
|
timeZone: options.timeZone,
|
|
hour: '2-digit',
|
|
hour12: false
|
|
});
|
|
const utcFormatter = new Intl.DateTimeFormat('en', {
|
|
timeZone: 'UTC',
|
|
hour: '2-digit',
|
|
hour12: false
|
|
});
|
|
const tzHour = parseInt(tzFormatter.format(tzDate));
|
|
const utcHour = parseInt(utcFormatter.format(tzDate));
|
|
const tzOffset = tzHour - utcHour;
|
|
const tzSign = tzOffset >= 0 ? '+' : '-';
|
|
const tzAbs = Math.abs(tzOffset);
|
|
timezone = `UTC ${tzSign}${tzAbs}`;
|
|
}
|
|
} catch {
|
|
// Fallback to browser timezone
|
|
timezone = `UTC ${offsetSign}${offsetAbs}`;
|
|
}
|
|
} else {
|
|
// Use browser's timezone offset
|
|
timezone = `UTC ${offsetSign}${offsetAbs}`;
|
|
}
|
|
|
|
return {
|
|
time: formattedTime,
|
|
timezone,
|
|
};
|
|
};
|
|
|