简体   繁体   中英

Detect if user's locale is set to 12-hour or 24-hour timeformat using javascript

how to check whether the user is using 12hr or 24hr time format using Javascript with or without using 3rd party library like moment.js I also tried new Date().toLocaleString() but it is not working tested in firefox and google chrome. firefox always shows 12hr format and chrome always shows 24hrs time format

Something like this:

/*
 * Detects browser's locale 24h time preference
 * It works by checking whether hour output contains a space ('1 AM' or '01')
 */
const isBrowserLocale24h = () =>
  !new Intl.DateTimeFormat(undefined, { hour: 'numeric' }).format(0).match(/\s/);

Check browser compatibility of Intl.DateTimeFormat .

You can perhaps fallback to the following, but I'm not sure whether AM/PM designation (whichever characters are used) is at the end of the output for all locales. This just checks whether the last character is numeric:

Number.isFinite(Number((new Date()).toLocaleString().slice(-1)))

Mario Bonaci's answer didn't work as expected for me though it pointed me to the right direction. Here's what I tried at first:

/*
 * Detects navigator locale 24h time preference
 * It works by checking whether hour output contains AM ('1 AM' or '01 h')
 */
const isBrowserLocale24h = () =>
  !new Intl.DateTimeFormat(undefined, { hour: "numeric" })
    .format(0)
    .match(/AM/);

It didn't work as expected as it apparently takes the browser's install language and not the user preferred language. Changing the undefined to navigator.language did the trick. Here, we're checking the time format based on the user's preferred language:

/*
 * Detects navigator locale 24h time preference
 * It works by checking whether hour output contains AM ('1 AM' or '01 h')
 * based on the user's preferred language
 */
const isBrowserLocale24h = () =>
  !new Intl.DateTimeFormat(navigator.language, { hour: "numeric" })
    .format(0)
    .match(/AM/);

@Marko Bonaci's answer was helpful. I researched his comment "I'm not sure whether AM/PM designation (whichever characters are used) is at the end of the output for all locales." A Google search listed this link stating a user's comment:

The Latin abbreviations am and pm (often written "am" and "pm", "AM" and "PM", or "AM" and "PM") are used in English, Portuguese (Brazilian) and Spanish. The equivalents in Greek are π.µ. and µ.µ. respectively.

This can be verified from the browser's console using the two letter ISO 639-1 code "el" or the three letter ISO 639-2 code "ell":

new Intl.DateTimeFormat(["el"], { hour: "numeric" }).format();
// or
new Intl.DateTimeFormat("ell", { hour: "numeric" }).format();

These lines will return a value with the localized "AM"/"PM" string:

'7 π.μ.'
'7 μ.μ.'

I ended up using his suggestion using the built-in ' Number ' object in JavaScript.

// UK english
Number.isInteger(Number(new Intl.DateTimeFormat("en-UK", { hour: "numeric" }).format()));
// Returns 'true'

// Greek
Number.isInteger(Number(new Intl.DateTimeFormat("el", { hour: "numeric" }).format()));
// Returns 'false'

// U.S.
Number.isInteger(Number(new Intl.DateTimeFormat("en-US", { hour: "numeric" }).format()));
// Returns 'false'

Here's my long-winded function:

const isBrowserLocaleClockType24h = (languages) => {
    // "In basic use without specifying a locale, DateTimeFormat
    // uses the default locale and default options."
    // Ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat#using_datetimeformat
    // To be sure of the browser's language (set by the user
    // and may be different than the operating system's default language)
    // set the 'languages' parameter to 'navigator.language'.
    // E.g. isBrowserLocaleClockType24h(navigator.language);
    if (!languages) { languages = []; }

    // The value of 'hr' will be in the format '0', '1', ... up to '24'
    // for a 24-hour clock type (depending on a clock type of
    // 'h23' or 'h24'. See:
    // developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale
    // Intl.Locale.prototype.hourCycles
    // Returns an Array of hour cycle identifiers, indicating either
    // the 12-hour format ("h11", "h12") or
    // the 24-hour format ("h23", "h24").

    // A 12-hour clock type value has the format '7 AM', '10 PM', or
    // '7 π.μ.' (if the locale language is Greek as specified
    // by the two letter ISO 639-1 code "el" or 
    // three letter ISO 639-2 code "ell").

    const hr = new Intl.DateTimeFormat(languages, { hour: "numeric" }).format();

    // If there's no space in the value of the 'hr' variable then
    // the value is a string representing a number between and
    // can include '0' and '24'. See comment above regarding "hourCycles".
    // Return 'true' if a space exists.
    //if (!hr.match(/\s/)) { return true; }
    // Or simply:
    // return !hr.match(/\s/);

    // Alternatively, check if the value of 'hr' is an integer.
    // E.g. Number.isInteger(Number('10 AM')) returns 'false'
    // E.g. Number.isInteger(Number('7 π.μ.')) returns 'false'
    // E.g. Number.isInteger(Number('10')) returns 'true'
    return Number.isInteger(Number(hr));
};

Usage:

const isBrowserLocaleClock24h = isBrowserLocaleClockType24h();
// or
const isBrowserLocaleClock24h = isBrowserLocaleClockType24h(navigator.language);

Using Intl.Locale().hourCycles

Lastly, for much newer browser's (except Firefox as of Dec 2022), there's new Intl.Locale(navigator.language).hourCycles listed on MDN .

// developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some#checking_whether_a_value_exists_in_an_array
const hourCycles = new Intl.Locale(navigator.language).hourCycles;
const isBrowserLocale24h = ["h23", "h24"].some(hourCycle => hourCycles.includes(hourCycle));

From

The Intl.Locale.prototype.hourCycle property is an accessor property that returns the time keeping format convention used by the locale.

There are 2 main types of time keeping conventions (clocks) used around the world: the 12 hour clock and the 24 hour clock. The hourCycle property makes it easier for JavaScript programmers to access the clock type used by a particular locale.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM