Overview

setLocale(tag) sets the language used for month and weekday names, formatLongAgo(), and getMonths(). The tag is a BCP 47 string such as "en", "fr", "de", or "hi". getLocale() returns that tag. With no call yet, mates uses navigator.language, then "en". setLocale(null) clears the override and goes back to that default.

setTimezoneOffset(minutes) stores minutes east of UTC (India is 330, New York standard time is -300) and drops any IANA name. setTimezone(entry) stores both the offset and the IANA name from getAllTimezones(). setTimezone(null) returns to the browser zone.

These setters are module globals. They are not atoms: calling them does not re-render a view by itself. Keep the choice in an atom, call the setter at the start of the template, then read date(). getCalendar weeks always start on Sunday. Day and month labels still follow the locale.

What each setting changes

Setting
Affects
Leaves alone
setLocale Month and weekday names, relative phrases, getMonths() The instant, and the Sunday-first calendar grid.
setTimezone Wall-clock hour, day boundary, Z/ZZ offset text, isToday The stored timestamp. ISO from toJSON stays UTC.
setTimezoneOffset The same wall clock, by a fixed minute offset IANA name. A later setTimezone replaces it.

Language tag

Switch en, fr, de, and hi. Weekday and month names, and the relative phrase, follow setLocale.

import { html, atom, date, setLocale, getLocale, renderApp } from 'mates';

const App = () => {
const locale = atom('en');

return () => {
setLocale(locale());
const now = date();
return html`
<div class="m-col m-gap">
<div class="m-flex m-gap-sm">
${['en', 'fr', 'de', 'hi'].map((tag) => html`
<button
class=${locale() === tag ? 'btn-primary' : 'btn'}
@click=${() => locale.set(tag)}
>${tag}</button>
`)}
</div>
<p>${now.format('dddd, MMMM D, YYYY')}</p>
<p class="muted">locale ${getLocale()} · ${now.formatLongAgo()}</p>
</div>
`;
};
};
renderApp(App, document.getElementById('app'));

Named zone

Local uses the browser zone. UTC, Kolkata, and New York come from getAllTimezones().

import {
html, atom, date, setTimezone, getTimezoneOffset, getAllTimezones, renderApp,
} from 'mates';

const CHOICES = [
{ id: 'local', label: 'Local' },
{ id: 'UTC', label: 'UTC' },
{ id: 'Asia/Kolkata', label: 'Kolkata' },
{ id: 'America/New_York', label: 'New York' },
];

const App = () => {
const zone = atom('local');
const zones = getAllTimezones();

return () => {
if (zone() === 'local') setTimezone(null);
else {
const match = zones.find((z) => z.name === zone());
if (match) setTimezone(match);
}
const now = date();
const off = getTimezoneOffset();
const sign = off >= 0 ? '+' : '';
return html`
<div class="m-col m-gap">
<div class="m-flex m-gap-sm">
${CHOICES.map((c) => html`
<button
class=${zone() === c.id ? 'btn-primary' : 'btn'}
@click=${() => zone.set(c.id)}
>${c.label}</button>
`)}
</div>
<p>${now.format('YYYY-MM-DD HH:mm')} ${now.format('Z')}</p>
<p class="muted">offset ${sign}${off} min</p>