{"id":76145,"date":"2024-02-27T11:59:52","date_gmt":"2024-02-27T10:59:52","guid":{"rendered":"https:\/\/phrase.com\/?p=76145"},"modified":"2024-03-06T20:10:11","modified_gmt":"2024-03-06T19:10:11","slug":"date-time-localization","status":"publish","type":"post","link":"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/","title":{"rendered":"A Guide to Date and Time Localization"},"content":{"rendered":"\n<div id=\"acf\/text-block_7391d202a985e02812017782859da643\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<p>We often think of internationalization (i18n) and localization (l10n) as translating text, ignoring all-too-important i18n aspects like date and time localization. Yet dates and times are represented in very different ways across geographies, and localizing them correctly is crucial to making users feel at home in our apps. This guide aims to shed some light on the intricacies of global dates and times. We\u2019ll cover formatting, working with time zones, understanding regional calendars, and taking a look at date and time picker UI.<\/p>\n<p>\ud83d\uddd2\ufe0f\u00a0While the examples in this guide target the browser and are written in JavaScript, the guide is intentionally tech-agnostic \u2014\u00a0there should be an equivalent to each concept in your platform and programming language of choice.<\/p>\n<p>\ud83d\uddd2\ufe0f Internationalization (i18n) and localization (l10n) allow us to make our apps available in different languages and to different regions, often for more profit. If you\u2019re new to i18n and l10n, check out our guide to <a href=\"https:\/\/phrase.com\/blog\/posts\/i18n-a-simple-definition\/\">internationalization<\/a>.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_69_1 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Overview<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#formatting-dates-and-times\" title=\"Formatting dates and times\">Formatting dates and times<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#default-formats\" title=\"Default formats\">Default formats<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#preset-formats\" title=\"Preset formats\">Preset formats<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#custom-formats\" title=\"Custom formats\">Custom formats<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#time-zones\" title=\"Time zones\">Time zones<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#utc\" title=\"UTC\">UTC<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#iana\" title=\"IANA\">IANA<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#iso-8601\" title=\"ISO 8601\">ISO 8601<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#code-examples\" title=\"Code examples\">Code examples<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#calendars\" title=\"Calendars\">Calendars<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#date-and-time-pickers\" title=\"Date and time pickers\">Date and time pickers<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/phrase.com\/blog\/posts\/date-time-localization\/#wrapping-up-key-takeaways-in-date-and-time-localization\" title=\"Wrapping up: Key takeaways in date and time localization\">Wrapping up: Key takeaways in date and time localization<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"formatting-dates-and-times\"><\/span>Formatting dates and times<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>How do we present dates and times to someone depending on where they hail from the world? We have to answer the second question first and <a href=\"https:\/\/phrase.com\/blog\/posts\/detecting-a-users-locale\/\">determine the user\u2019s locale<\/a>. This will often be their system locale: If a user sets her operating system language to French and region to Canada, the default locale of an app presented to this user is likely <code>fr-CA<\/code> (French Canada).<\/p>\n<p>\ud83d\uddd2\ufe0f\u00a0A locale defines a language, a region, and sometimes more. Locales typically use <a href=\"https:\/\/en.wikipedia.org\/wiki\/IETF_language_tag\">IETF BCP 47 language tags<\/a>, like <code>en<\/code> for English, <code>fr<\/code> for French, and <code>es<\/code> for Spanish. Adding a region with the ISO Alpha-2 code (e.g., <code>BH<\/code> for Bahrain, <code>CN<\/code> for China, <code>US<\/code> for the United States) is recommended for accurate date and number localization. So a complete locale might look like <code>en-US<\/code> for American English or <code>zh-CN<\/code> for Chinese as used in China.<\/p>\n<p>\ud83d\udd17 Explore more language tags on <a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_ISO_639-1_codes\">Wikipedia<\/a> and find country codes through the ISO&#8217;s <a href=\"https:\/\/www.iso.org\/obp\/ui\/#search\">search tool<\/a>.<\/p>\n<p>\ud83d\uddd2\ufe0f Date and time formats are <em>region<\/em>-specific, so it\u2019s important to use qualified locales when formatting dates e.g. use <code>en-US<\/code>, not <code>en<\/code>.<\/p>\n<p>With our essential background in place, the straightforward approach to formatting localized dates and times involves creating a date object and then utilizing a native date formatting library. Let\u2019s take a look at an example in the browser using the native JavaScript <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Intl\/DateTimeFormat\">Intl.DateTimeFormat<\/a> formatter.<\/p>\n<p><!-- notionvc: 2b8835ba-da0c-46f2-bd4f-ef15eecee530 --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> date = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>(<span class=\"hljs-string\">\"2024-01-27T14:00:00Z\"<\/span>);\n<span class=\"hljs-keyword\">const<\/span> formatter = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Intl<\/span>.DateTimeFormat();\n\nformatter.format(date);\n<span class=\"hljs-comment\">\/\/ =&gt; 1\/27\/2024<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_8a5bbe8733b870c9f4c66e3c9293e61e\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<p>Our <code>date<\/code> represents 2024-01-27 2:00 PM in UTC (more on time zones a bit later). We create an <code>Intl.DateTimeFormat<\/code> without specifying any options, which means we want default date formatting for the default locale.<\/p>\n<p>The <code>format()<\/code> call spits out \u201c1\/27\/2024\u201d when <code>en-US<\/code> (English America) is determined to be the default locale, respecting the American default date format of Month\/Day\/Year.<\/p>\n<p>On my machine, however, the same code outputs \u201c2024-01-27\u201d. This is because my operating system is set to <code>en-CA<\/code> (English Canada), and Year-Month-Day is the default Canadian date format.<\/p>\n<p>\ud83d\uddd2\ufe0f\u00a0<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Intl\/DateTimeFormat\/DateTimeFormat#browser_compatibility\">Intl.DateTimeFormat is available natively in all modern browsers and Node.js<\/a>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"default-formats\"><\/span>Default formats<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>When we don\u2019t provide specific formatting options to a date formatting library, we often get the default format for a given locale. Here are some default date formats for various locales:<\/p>\n<p><!-- notionvc: 8756999e-30b7-4477-b5dd-aa57d1fb5665 --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> date = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>(<span class=\"hljs-string\">\"2024-01-27T14:00:00Z\"<\/span>);\n\n<span class=\"hljs-comment\">\/\/ We use `date.toLocaleDateString(\"en-US\")` for<\/span>\n<span class=\"hljs-comment\">\/\/ the examples below. This is a shortcut for<\/span>\n<span class=\"hljs-comment\">\/\/ `new Intl.DateTimeFormat(\"en-US\").format(date)`<\/span>\n<span class=\"hljs-comment\">\/\/ See \ud83d\uddd2\ufe0f below for more info.<\/span>\n\n<span class=\"hljs-comment\">\/\/ English-America<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"en-US\"<\/span>);\n<span class=\"hljs-comment\">\/\/ =&gt; \"1\/27\/2024\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Arabic-Egypt<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"ar-EG\"<\/span>);\n<span class=\"hljs-comment\">\/\/ =&gt; \"\u0662\u0667\u200f\/\u0661\u200f\/\u0662\u0660\u0662\u0664\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Hindi-India<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"hi-IN\"<\/span>);\n<span class=\"hljs-comment\">\/\/ =&gt; \"27\/1\/2024\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Russian-Russia<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"ru-RU\"<\/span>);\n<span class=\"hljs-comment\">\/\/ =&gt; \"27.01.2024\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Chinese-China<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"zh-CN\"<\/span>);\n<span class=\"hljs-comment\">\/\/ =&gt; \"2024\/1\/27\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Japanese-Japan<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"jp-JP\"<\/span>);\n<span class=\"hljs-comment\">\/\/ =&gt; \"2024-01-27\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_a6d2e6c2d97293085ec78be0ee0e744b\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<p>\ud83d\uddd2\ufe0f\u00a0<code>Date.toLocaleDateString()<\/code> uses <code>Intl.DateTimeFormat<\/code> under the hood when it\u2019s available. Read more on the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Date\/toLocaleDateString\">Date MDN entry<\/a>.<\/p>\n<p>\u201cWhat about times?\u201d you might be asking. Of course, we can often use native libraries to format localized times as well. Here are some default time formats:<\/p>\n<p><!-- notionvc: 57c865fc-5d1d-4d6e-8b92-bab09d801f1f --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ Date object with time of 2 PM UTC<\/span>\n<span class=\"hljs-keyword\">const<\/span> date = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>(<span class=\"hljs-string\">\"2024-01-27T14:00:00Z\"<\/span>);\n\n<span class=\"hljs-comment\">\/\/ The below calls to<\/span>\n<span class=\"hljs-comment\">\/\/ `date.ToLocaleTimeString(...)` are equivalent to<\/span>\n<span class=\"hljs-comment\">\/\/ `new Intl.DateTimeFormat(\"en-US\", {<\/span>\n<span class=\"hljs-comment\">\/\/    timeZone: \"UTC\",<\/span>\n<span class=\"hljs-comment\">\/\/    timeStyle: \"medium\",<\/span>\n<span class=\"hljs-comment\">\/\/  }).format(date)`<\/span>\n<span class=\"hljs-comment\">\/\/ See \ud83d\uddd2\ufe0f below for more info.<\/span>\n\n<span class=\"hljs-comment\">\/\/ English-America<\/span>\ndate.toLocaleTimeString(<span class=\"hljs-string\">\"en-US\"<\/span>, { <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"UTC\"<\/span> });\n<span class=\"hljs-comment\">\/\/ =&gt; \"2:00:00 PM\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Arabic-Egypt<\/span>\ndate.toLocaleTimeString(<span class=\"hljs-string\">\"ar-EG\"<\/span>, { <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"UTC\"<\/span> });\n<span class=\"hljs-comment\">\/\/ =&gt; \"\u0662:\u0660\u0660:\u0660\u0660 \u0645\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Hindi-India<\/span>\ndate.toLocaleTimeString(<span class=\"hljs-string\">\"hi-IN\"<\/span>, { <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"UTC\"<\/span> });\n<span class=\"hljs-comment\">\/\/ =&gt; \"2:00:00 pm\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Russian-Russia<\/span>\ndate.toLocaleTimeString(<span class=\"hljs-string\">\"ru-RU\"<\/span>, { <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"UTC\"<\/span> });\n<span class=\"hljs-comment\">\/\/ =&gt; \"14:00:00\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Chinese-China<\/span>\ndate.toLocaleTimeString(<span class=\"hljs-string\">\"zh-CN\"<\/span>, { <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"UTC\"<\/span> });\n<span class=\"hljs-comment\">\/\/ =&gt; \"14:00:00\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Japanese-Japan<\/span>\ndate.toLocaleTimeString(<span class=\"hljs-string\">\"jp-JP\"<\/span>, { <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"UTC\"<\/span> });\n<span class=\"hljs-comment\">\/\/ =&gt; \"2:00:00 p.m.\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_716273aaf2a29e53ee61183661e15a2b\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<p>\ud83d\uddd2\ufe0f\u00a0Just like <code>Date.toLocaleDateString()<\/code>, <code>Date.toLocaleTimeString()<\/code> uses <code>Intl.DateTimeFormat<\/code> under the hood when it\u2019s available. Read more on the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Date\/toLocaleTimeString\">Date MDN entry<\/a>.<\/p>\n<p>Note that in the above examples, we set the time zone to UTC using the <code>timeZone<\/code> option. This is to maintain a consistent output for demonstration purposes. If we omit the option, the system time zone will be used. I\u2019m currently in the UTC +1 time zone, so the <code>en-US<\/code> example would output the following on my machine: \u201c3:00:00 PM\u201d.<\/p>\n<p>\ud83d\uddd2\ufe0f Again, we\u2019ll tackle time zones in a bit more detail a bit later.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"preset-formats\"><\/span>Preset formats<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Beyond default formats, we often want to control the length of the date and time output. We can achieve this with preset formats that many native formatting libraries offer. In the JavaScript <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Intl\/DateTimeFormat\/DateTimeFormat#parameters\">Intl.DateTimeFormat options<\/a>, these are <code>dateStyle<\/code> and <code>timeStyle<\/code>. If you\u2019re working on a different platform, there are likely equivalents in that platform\u2019s formatting libraries.<\/p>\n<ul>\n<li><code>dateStyle<\/code> \u2014\u00a0can be <code>\"full\"<\/code>, <code>\"long\"<\/code>, <code>\"medium\"<\/code>, or <code>\"short\u201d<\/code>.<\/li>\n<li><code>timeStyle<\/code> \u2014\u00a0can be <code>\"full\"<\/code>, <code>\"long\"<\/code>, <code>\"medium\"<\/code>, or <code>\"short\u201d<\/code>.<\/li>\n<\/ul>\n<p>Let\u2019s see what these look like in action:<\/p>\n<p><!-- notionvc: 30398835-7afa-4597-849c-abe88748531d --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> date = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>(<span class=\"hljs-string\">\"2024-01-27T14:00:00Z\"<\/span>);\n\n<span class=\"hljs-keyword\">const<\/span> shortOptions = {\n  <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"UTC\"<\/span>,\n  <span class=\"hljs-attr\">dateStyle<\/span>: <span class=\"hljs-string\">\"short\"<\/span>,\n  <span class=\"hljs-attr\">timeStyle<\/span>: <span class=\"hljs-string\">\"short\"<\/span>,\n};\n\n<span class=\"hljs-comment\">\/\/ English-America<\/span>\n<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Intl<\/span>.DateTimeFormat(<span class=\"hljs-string\">\"en-US\"<\/span>, shortOptions)\n  .format(date);\n<span class=\"hljs-comment\">\/\/ =&gt; \"1\/27\/24, 2:00 PM\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Arabic-Egypt<\/span>\n<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Intl<\/span>.DateTimeFormat(<span class=\"hljs-string\">\"ar-EG\"<\/span>, shortOptions)\n  .format(date);\n<span class=\"hljs-comment\">\/\/ =&gt; \"\u0662\u0667\u200f\/\u0661\u200f\/\u0662\u0660\u0662\u0664\u060c \u0662:\u0660\u0660 \u0645\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Chinese-China<\/span>\n<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Intl<\/span>.DateTimeFormat(<span class=\"hljs-string\">\"zh-CN\"<\/span>, shortOptions)\n  .format(date);\n<span class=\"hljs-comment\">\/\/ =&gt; \"2024\/1\/27 14:00\"<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> fullOptions = {\n  <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"UTC\"<\/span>,\n  <span class=\"hljs-attr\">dateStyle<\/span>: <span class=\"hljs-string\">\"full\"<\/span>,\n  <span class=\"hljs-attr\">timeStyle<\/span>: <span class=\"hljs-string\">\"full\"<\/span>,\n};\n\n<span class=\"hljs-comment\">\/\/ English-America<\/span>\n<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Intl<\/span>.DateTimeFormat(<span class=\"hljs-string\">\"en-US\"<\/span>, fullOptions)\n  .format(date);\n<span class=\"hljs-comment\">\/\/ =&gt; \"Saturday, January 27, 2024 at 2:00:00 PM Coordinated Universal Time\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Arabic-Egypt<\/span>\n<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Intl<\/span>.DateTimeFormat(<span class=\"hljs-string\">\"ar-EG\"<\/span>, fullOptions)\n  .format(date);\n<span class=\"hljs-comment\">\/\/ =&gt; \"\u0627\u0644\u0633\u0628\u062a\u060c \u0662\u0667 \u064a\u0646\u0627\u064a\u0631 \u0662\u0660\u0662\u0664 \u0641\u064a \u0662:\u0660\u0660:\u0660\u0660 \u0645 \u0627\u0644\u062a\u0648\u0642\u064a\u062a \u0627\u0644\u0639\u0627\u0644\u0645\u064a \u0627\u0644\u0645\u0646\u0633\u0642\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Chinese-China<\/span>\n<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Intl<\/span>.DateTimeFormat(<span class=\"hljs-string\">\"zh-CN\"<\/span>, fullOptions).format(date);\n<span class=\"hljs-comment\">\/\/ =&gt; \"2024\u5e741\u670827\u65e5\u661f\u671f\u516d \u534f\u8c03\u4e16\u754c\u65f6 14:00:00\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_4ea12234a30ecdcd80f59c706d19aef3\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<p>Preset options often conform to the conventions of the given locale. We can just set the length of the format we want and rely on the formatting library to handle the per-locale details.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"custom-formats\"><\/span>Custom formats<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Complete control over our date and time formatting is achieved via granular format specifiers. For example, we might want to show only the year of a given date or force 24-hour time representation. Any date formatting library worth its salt will allow us this level of customization. Here are examples using JavaScript\u2019s <code>Intl.DateTimeFormat<\/code>:<\/p>\n<p><!-- notionvc: a205dc9e-cf4d-430a-a39b-c0afce703dbe --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> date = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>(<span class=\"hljs-string\">\"2024-01-27T14:00:00Z\"<\/span>);\n\n<span class=\"hljs-keyword\">const<\/span> options = {\n  <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"UTC\"<\/span>,\n  <span class=\"hljs-attr\">timeZoneName<\/span>: <span class=\"hljs-string\">\"short\"<\/span>,\n  <span class=\"hljs-attr\">year<\/span>: <span class=\"hljs-string\">\"2-digit\"<\/span>,\n  <span class=\"hljs-attr\">month<\/span>: <span class=\"hljs-string\">\"narrow\"<\/span>,\n  <span class=\"hljs-attr\">weekday<\/span>: <span class=\"hljs-string\">\"short\"<\/span>,\n  <span class=\"hljs-attr\">day<\/span>: <span class=\"hljs-string\">\"numeric\"<\/span>,\n  <span class=\"hljs-attr\">hourCycle<\/span>: <span class=\"hljs-string\">\"h24\"<\/span>,\n  <span class=\"hljs-attr\">hour<\/span>: <span class=\"hljs-string\">\"numeric\"<\/span>,\n  <span class=\"hljs-attr\">minute<\/span>: <span class=\"hljs-string\">\"numeric\"<\/span>,\n};\n\n<span class=\"hljs-comment\">\/\/ English-America<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"en-US\"<\/span>, options);\n<span class=\"hljs-comment\">\/\/ =&gt; \"Sat, J 27, 24, 14:00 UTC\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Arabic-Egypt<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"ar-EG\"<\/span>, options);\n<span class=\"hljs-comment\">\/\/ =&gt; \"\u0627\u0644\u0633\u0628\u062a\u060c \u0662\u0667 \u064a \u0662\u0664\u060c \u0661\u0664:\u0660\u0660 UTC\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Hindi-India<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"hi-IN\"<\/span>, options);\n<span class=\"hljs-comment\">\/\/ =&gt; \"\u0936\u0928\u093f, 27 \u091c 24, 14:00 UTC\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Russian-Russia<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"ru-RU\"<\/span>, options);\n<span class=\"hljs-comment\">\/\/ =&gt; \"\u0441\u0431, 27 \u042f 24 \u0433., 14:00 UTC\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Chinese-China<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"zh-CN\"<\/span>, options);\n<span class=\"hljs-comment\">\/\/ =&gt; \"24\u5e741\u670827\u65e5\u5468\u516d UTC 14:00\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Japanese-Japan<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"jp-JP\"<\/span>, options);\n<span class=\"hljs-comment\">\/\/ =&gt; \"Sat, J 27, 24, 14:00 UTC\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_b516d3c66b7d9bde31a994f1c9ec36a7\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<p>\ud83d\udd17\u00a0<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Intl\/DateTimeFormat\/DateTimeFormat#parameters\">Check out all the formatting options provided by Intl.DateTimeFormat on the MDN documentation<\/a>.<\/p>\n<p>\ud83d\uddd2\ufe0f You may have noticed that localizing dates and times often relies on local number systems. The previous Arabic example uses both Eastern Arabic numerals and Arabic script, \u201c\u0627\u0644\u0633\u0628\u062a\u060c \u0662\u0667 \u064a \u0662\u0664\u060c \u0661\u0664:\u0660\u0660 UTC\u201d. Modern systems and their formatting libraries often take care of all of this for us, but it\u2019s good to bear in mind.<\/p>\n<p>\ud83d\udd17 Our <a href=\"https:\/\/phrase.com\/blog\/posts\/number-localization\/\">Concise Guide to Number Localization<\/a> covers numeral systems, currency, and more.<\/p>\n<p>\ud83d\uddd2\ufe0f To represent written days of the week, months, etc. we of course have to use the language and script of the target locale. Again, something to be mindful of.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"time-zones\"><\/span>Time zones<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We usually stick to UTC or the server&#8217;s time zone for keeping track of times on the back end. We can then convert the date during formatting to match the user&#8217;s local time zone on the front end. The key here is knowing the source and destination time zones so we can nail the conversion.<\/p>\n<p>\ud83d\uddd2\ufe0f Heads up if you&#8217;re working with full-stack frameworks like Next.js or SvelteKit \u2014 mismatched time zones between server-side rendering and client-side can lead to those pesky hydration errors. One fix is to keep your time zone consistent on both the server and client side by setting it once in a shared config.<\/p>\n<p>When working with time zones, we often use a set of standards, primarily UTC, IANA, and ISO 8601. Let\u2019s go over these briefly.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"utc\"><\/span>UTC<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Coordinated_Universal_Time\">UTC (Coordinated Universal Time)<\/a> is the modern standard for global civil time, refining GMT (Greenwich Mean Time) with atomic clock precision alongside Earth&#8217;s rotation. Time zones are represented as offsets from UTC. For example, <code>UTC-05:00<\/code> is equivalent to Eastern Standard Time (EST).<\/p>\n<p>\ud83d\udd17 Dive deeper into UTC&#8217;s specifics on its <a href=\"https:\/\/en.wikipedia.org\/wiki\/Coordinated_Universal_Time\">Wikipedia page<\/a>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"iana\"><\/span>IANA<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Internet_Assigned_Numbers_Authority\">Internet Assigned Numbers Authority (IANA)<\/a> handles crucial Internet roles like IP addressing, DNS management, and protocol IDs to keep the net running smoothly. Its <a href=\"https:\/\/www.iana.org\/time-zones\">Time Zone Database<\/a> tracks global time zones, including daylight saving changes and UTC offsets, updated for political shifts. Time zones use an <code>Area\/Location<\/code> format, like <code>America\/New_York<\/code>, and have abbreviations such as <code>EST<\/code> (Eastern Standard Time).<\/p>\n<p>\ud83d\udd17 Dive into the details on the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tz_database\">tz database&#8217;s Wikipedia page<\/a>.<\/p>\n<p>\ud83d\udd17\u00a0The Wikipedia <a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_tz_database_time_zones\">List of tz database time zones<\/a> is an excellent lookup.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"iso-8601\"><\/span>ISO 8601<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>We&#8217;ve been using the ISO 8601 format for dates, like <code>2024-02-23T15:45:00Z<\/code>, which includes the date followed by <code>T<\/code> and the time in 24-hour format. <code>Z<\/code> indicates UTC, but you can specify other time zones with an offset, like <code>+03:00<\/code> e.g. <code>2024-02-23T15:45:00+03:00<\/code>.<\/p>\n<p>\ud83d\uddd2\ufe0f\u00a0ISO 8601 is a common standard, but your source date can be formatted in a variety of ways. Make sure you know the format when parsing.<\/p>\n<p>\ud83d\udd17\u00a0Learn more on <a href=\"https:\/\/en.wikipedia.org\/wiki\/ISO_8601\">Wikipedia&#8217;s ISO 8601 page<\/a>.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"code-examples\"><\/span>Code examples<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Let\u2019s see how these standards work together when localizing dates and times. Here are examples in JavaScript using <code>Intl.DateTimeFormat<\/code>:<\/p>\n<p><!-- notionvc: d0204296-6089-4829-82be-5ccf3b9ba72b --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ Note how the `Date` object knows how to parse<\/span>\n<span class=\"hljs-comment\">\/\/ the ISO 8601 format. The following datetime<\/span>\n<span class=\"hljs-comment\">\/\/ includes 3:45 PM in the UTC +01:00 time<\/span>\n<span class=\"hljs-comment\">\/\/ zone.<\/span>\n<span class=\"hljs-keyword\">const<\/span> date = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>(<span class=\"hljs-string\">\"2024-02-27T15:45:00+01:00\"<\/span>);\n\ndate.toLocaleString(<span class=\"hljs-string\">\"en-US\"<\/span>, {\n  <span class=\"hljs-comment\">\/\/ Convert to target IANA `timeZone` when<\/span>\n  <span class=\"hljs-comment\">\/\/ formatting.<\/span>\n  <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"America\/New_York\"<\/span>,\n  <span class=\"hljs-attr\">dateStyle<\/span>: <span class=\"hljs-string\">\"medium\"<\/span>,\n  <span class=\"hljs-attr\">timeStyle<\/span>: <span class=\"hljs-string\">\"full\"<\/span>,\n});\n<span class=\"hljs-comment\">\/\/ =&gt; \"Feb 27, 2024, 9:45:00 AM Eastern Standard Time\"<\/span>\n\ndate.toLocaleString(<span class=\"hljs-string\">\"en-US\"<\/span>, {\n  <span class=\"hljs-comment\">\/\/ Use the abbreviated time zone; this <\/span>\n  <span class=\"hljs-comment\">\/\/ affects conversion as well as formatting. <\/span>\n  <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"EST\"<\/span>,\n  <span class=\"hljs-attr\">dateStyle<\/span>: <span class=\"hljs-string\">\"medium\"<\/span>,\n  <span class=\"hljs-attr\">timeStyle<\/span>: <span class=\"hljs-string\">\"full\"<\/span>,\n});\n<span class=\"hljs-comment\">\/\/ =&gt; \"Feb 27, 2024, 9:45:00 AM GMT-05:00\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Format in Hindi-India and convert to <\/span>\n<span class=\"hljs-comment\">\/\/ the Indian time zone.<\/span>\ndate.toLocaleString(<span class=\"hljs-string\">\"hi-IN\"<\/span>, {\n  <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"Asia\/Kolkata\"<\/span>,\n  <span class=\"hljs-attr\">dateStyle<\/span>: <span class=\"hljs-string\">\"medium\"<\/span>,\n  <span class=\"hljs-attr\">timeStyle<\/span>: <span class=\"hljs-string\">\"full\"<\/span>,\n});\n<span class=\"hljs-comment\">\/\/ =&gt; \"27 \u092b\u093c\u0930\u0970 2024, 8:15:00 pm \u092d\u093e\u0930\u0924\u0940\u092f \u092e\u093e\u0928\u0915 \u0938\u092e\u092f\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Chinese-China in the Shanghai time zone.<\/span>\ndate.toLocaleString(<span class=\"hljs-string\">\"zh-CH\"<\/span>, {\n  <span class=\"hljs-attr\">timeZone<\/span>: <span class=\"hljs-string\">\"Asia\/Shanghai\"<\/span>,\n  <span class=\"hljs-attr\">dateStyle<\/span>: <span class=\"hljs-string\">\"medium\"<\/span>,\n  <span class=\"hljs-attr\">timeStyle<\/span>: <span class=\"hljs-string\">\"full\"<\/span>,\n})\n<span class=\"hljs-comment\">\/\/ =&gt; \"2024\u5e742\u670827\u65e5 \u4e2d\u56fd\u6807\u51c6\u65f6\u95f4 22:45:00\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_d3feed123134b925d24f83244cc3690c\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<h2><span class=\"ez-toc-section\" id=\"calendars\"><\/span>Calendars<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>While the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Gregorian_calendar\">Gregorian calendar<\/a> \u2014\u00a0Jan, Feb, etc. \u2014\u00a0 is ubiquitous, there are many regional and cultural calendars used all over the world. This is important when localizing, since some calendars, like the Islamic, Persian, and Buddhist calendars are used on a day-to-day basis. Indeed, certain regions use a non-Gregorian calendar as the <em>default<\/em>.<\/p>\n<p>Some of these calendars serve cultural purposes. Some are solar, others are lunar, and each has its starting year.<\/p>\n<figure id=\"attachment_76151\" aria-describedby=\"caption-attachment-76151\" style=\"width: 568px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-76151\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/wikipedia-gregorian-calendar.png\" alt=\"A listing of months in the Gregorian calendar. Source: Wikipedia.\" width=\"568\" height=\"832\" srcset=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/wikipedia-gregorian-calendar.png 568w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/wikipedia-gregorian-calendar-205x300.png 205w\" sizes=\"(max-width: 568px) 100vw, 568px\" \/><figcaption id=\"caption-attachment-76151\" class=\"wp-caption-text\">A listing of months in the Gregorian calendar. Source: Wikipedia.<\/figcaption><\/figure>\n<figure id=\"attachment_76157\" aria-describedby=\"caption-attachment-76157\" style=\"width: 1930px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-76157\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/buddhist-calendar-months.png\" alt=\"A listing of months in the Buddhist calendar. Source: Wikipedia.\" width=\"1930\" height=\"1310\" srcset=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/buddhist-calendar-months.png 1930w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/buddhist-calendar-months-300x204.png 300w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/buddhist-calendar-months-1024x695.png 1024w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/buddhist-calendar-months-768x521.png 768w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/buddhist-calendar-months-1536x1043.png 1536w\" sizes=\"(max-width: 1930px) 100vw, 1930px\" \/><figcaption id=\"caption-attachment-76157\" class=\"wp-caption-text\">A listing of months in the Buddhist calendar. Source: Wikipedia.<\/figcaption><\/figure>\n<p>Here are some examples of regions that use non-Gregorian calendars as their default:<\/p>\n<p><!-- notionvc: 706d0788-fada-4fa0-b54e-dd6138e3f146 --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> date = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>(<span class=\"hljs-string\">\"2024-01-27T14:00:00Z\"<\/span>);\n\n<span class=\"hljs-comment\">\/\/ Arabic Saudi-Arabia;<\/span>\n<span class=\"hljs-comment\">\/\/ converts to the Islamic Hijri calendar.<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"ar-SA\"<\/span>);\n<span class=\"hljs-comment\">\/\/ =&gt; \"\u0661\u0665\u200f\/\u0667\u200f\/\u0661\u0664\u0664\u0665 \u0647\u0640\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ We can provide the calendar as a<\/span>\n<span class=\"hljs-comment\">\/\/ manual override formatting option.<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"en-US\"<\/span>, { <span class=\"hljs-attr\">calendar<\/span>: <span class=\"hljs-string\">\"islamic\"<\/span> })\n<span class=\"hljs-comment\">\/\/ =&gt; \"7\/16\/1445 AH\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Persian-Iran;<\/span>\n<span class=\"hljs-comment\">\/\/ converts to the Persian calendar.<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"fa-IR\"<\/span>);\n<span class=\"hljs-comment\">\/\/ =&gt; \"\u06f1\u06f4\u06f0\u06f2\/\u06f1\u06f1\/\u06f7\"<\/span>\n\ndate.toLocaleDateString(<span class=\"hljs-string\">\"en-US\"<\/span>, { <span class=\"hljs-attr\">calendar<\/span>: <span class=\"hljs-string\">\"persian\"<\/span> });\n<span class=\"hljs-comment\">\/\/ =&gt; \"11\/7\/1402 AP\"<\/span>\n\n<span class=\"hljs-comment\">\/\/ Thai-Thailand;<\/span>\n<span class=\"hljs-comment\">\/\/ converts to the Buddhist calendar.<\/span>\ndate.toLocaleDateString(<span class=\"hljs-string\">\"th-TH\"<\/span>);\n<span class=\"hljs-comment\">\/\/ =&gt; \"27\/1\/2567\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_c1bd8d8b8340cd625560b49d586dcf31\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<h2><span class=\"ez-toc-section\" id=\"date-and-time-pickers\"><\/span>Date and time pickers<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We\u2019ve been looking at formatting output so far. Let\u2019s switch to input. To make our users\u2019 lives easier, we often present them with a date picker when ask them for date input. On the web, we can use the <code>date<\/code>, <code>time<\/code> and <code>datetime-local<\/code> inputs.<\/p>\n<p><!-- notionvc: 0402d226-f94e-4202-a73a-b4c2ff08bba7 --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"date\"<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_c4d9bddb788e8badd221ea3542e248f8\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<p>&nbsp;<\/p>\n<figure id=\"attachment_76163\" aria-describedby=\"caption-attachment-76163\" style=\"width: 628px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-76163\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/firefox-date.png\" alt=\"The Firefox browser date picker.\" width=\"628\" height=\"712\" srcset=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/firefox-date.png 628w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/firefox-date-265x300.png 265w\" sizes=\"(max-width: 628px) 100vw, 628px\" \/><figcaption id=\"caption-attachment-76163\" class=\"wp-caption-text\">The Firefox browser date picker.<\/figcaption><\/figure>\n<p>\ud83d\udd17\u00a0Learn more from the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/input\/date\">MDN date input entry<\/a>.<\/p>\n<p><!-- notionvc: 32b3aacb-468d-4f61-8b57-c6e6933f3e61 --><\/p>\n<p><!-- notionvc: b8ec613a-3da0-4e75-ab3b-384414fa0cf0 --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"time\"<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_29290197954d60095126074c99c8382d\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<figure id=\"attachment_76169\" aria-describedby=\"caption-attachment-76169\" style=\"width: 394px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-76169 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/arc-time.png\" alt=\"The Arc (Chromium-based) browser time picker.\" width=\"394\" height=\"614\" srcset=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/arc-time.png 394w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/arc-time-193x300.png 193w\" sizes=\"(max-width: 394px) 100vw, 394px\" \/><figcaption id=\"caption-attachment-76169\" class=\"wp-caption-text\">The Arc (Chromium-based) browser time picker.<\/figcaption><\/figure>\n<p>\ud83d\udd17 Learn more from the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/input\/time\">MDN time input entry<\/a>.<\/p>\n<p>To combine both date and time, can use the the <code>datetime-local<\/code> input.<\/p>\n<p><!-- notionvc: 847ec5a2-5e9e-4f96-81a3-426e44428c38 --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"datetime-local\"<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div id=\"acf\/text-block_60088ec43e562b76150db380aa5628c4\" class=\"pxblock pxblock--text alignfull spacing--default bg--white\">\n\n\t\n\t<div class=\"container\">\n\t\t<div class=\"wysiwyg animate-in\">\n\t\t\t<p>&nbsp;<\/p>\n<figure id=\"attachment_76175\" aria-describedby=\"caption-attachment-76175\" style=\"width: 830px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-76175\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/arc-datetime-local.png\" alt=\"The Arc browser datetime-local picker.\" width=\"830\" height=\"666\" srcset=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/arc-datetime-local.png 830w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/arc-datetime-local-300x241.png 300w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/arc-datetime-local-768x616.png 768w\" sizes=\"(max-width: 830px) 100vw, 830px\" \/><figcaption id=\"caption-attachment-76175\" class=\"wp-caption-text\">The Arc browser datetime-local picker.<\/figcaption><\/figure>\n<p>\ud83d\udd17\u00a0Learn more from the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/input\/datetime-local\">MDN datetime-local input<\/a> <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/input\/time\">entry<\/a>.<\/p>\n<p>Unfortunately, the native browser pickers seem stuck on Gregorian calendars, with no manual or automatic localization switching to other calendars. To get truly localizable date pickers in our web apps, we have to roll our own or use a library like <a href=\"https:\/\/github.com\/react-dates\/react-dates\">react-dates<\/a> (for React).<\/p>\n<figure id=\"attachment_76181\" aria-describedby=\"caption-attachment-76181\" style=\"width: 1268px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-76181 size-full\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/react-dates-picker-persian.png\" alt=\"The react-dates date picker showing the Persian calendar.\" width=\"1268\" height=\"708\" srcset=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/react-dates-picker-persian.png 1268w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/react-dates-picker-persian-300x168.png 300w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/react-dates-picker-persian-1024x572.png 1024w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/react-dates-picker-persian-768x429.png 768w\" sizes=\"(max-width: 1268px) 100vw, 1268px\" \/><figcaption id=\"caption-attachment-76181\" class=\"wp-caption-text\">The react-dates date picker showing the Persian calendar.<\/figcaption><\/figure>\n<p><!-- notionvc: c9a5737f-73e4-4361-a895-3ee52f774fb2 --><\/p>\n<p>&nbsp;<\/p>\n<p>If you\u2019re working on an operating system platform, like Android or iOS, you\u2019ll find their native date pickers automatically localize their numeral systems, text labels, and layout direction per the user\u2019s language. They might still largely stick to the Gregorian calendar, however.<\/p>\n<figure id=\"attachment_76187\" aria-describedby=\"caption-attachment-76187\" style=\"width: 604px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-76187\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/ar-android-date-picker.png\" alt=\"The native Android date picker localized for Arabic users.\" width=\"604\" height=\"1022\" srcset=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/ar-android-date-picker.png 604w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/ar-android-date-picker-177x300.png 177w\" sizes=\"(max-width: 604px) 100vw, 604px\" \/><figcaption id=\"caption-attachment-76187\" class=\"wp-caption-text\">The native Android date picker localized for Arabic users.<\/figcaption><\/figure>\n<figure id=\"attachment_76193\" aria-describedby=\"caption-attachment-76193\" style=\"width: 602px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-76193\" src=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/ar-android-time-picker.png\" alt=\"The native Android time picker localized for Arabic users.\" width=\"602\" height=\"828\" srcset=\"https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/ar-android-time-picker.png 602w, https:\/\/phrase.com\/wp-content\/uploads\/2024\/02\/ar-android-time-picker-218x300.png 218w\" sizes=\"(max-width: 602px) 100vw, 602px\" \/><figcaption id=\"caption-attachment-76193\" class=\"wp-caption-text\">The native Android time picker localized for Arabic users.<\/figcaption><\/figure>\n<p>\ud83d\udd17 <a href=\"https:\/\/phrase.com\/blog\/posts\/localized-date-time-android\/\">How to Localize Date and Time Formats in Android<\/a> is a deep dive into the subject.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"wrapping-up-key-takeaways-in-date-and-time-localization\"><\/span><strong>Wrapping up: Key takeaways in date and time localization<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>As we conclude our exploration of localizing dates and times, we hope that you can see that this aspect of localization is more than a mere afterthought \u2014 it&#8217;s a cornerstone of creating truly global and inclusive applications.<\/p>\n<p>Here are the key takeaways from this guide:<\/p>\n<ul>\n<li><strong>Determine the user\u2019s locale<\/strong>: Identifying the user&#8217;s locale is the first step in presenting dates and times that reflect their cultural and regional standards.<\/li>\n<li><strong>Understand locale definitions<\/strong>: Recognize that a locale encompasses language, region, and sometimes additional nuances, influencing how dates and times should be formatted.<\/li>\n<li><strong>Use native formatting libraries<\/strong>: Leverage native date formatting libraries, which automatically adjust to the user\u2019s locale.<\/li>\n<li><strong>Utilize default and custom formats<\/strong>: Whether adopting default formats or customizing them for complete control, be mindful of the locale&#8217;s conventions for representing dates and times (again libraries help a lot here).<\/li>\n<li><strong>Account for time zones<\/strong>: Ensure that dates and times are correctly adjusted for the user&#8217;s location.<\/li>\n<li><strong>Explore calendar diversity<\/strong>: Study the regions where you\u2019re serving your app and see if they use local non-Gregorian calendars.<\/li>\n<li><strong>Prefer accessible date and time pickers<\/strong>: Choose date and time pickers that support localization, at least showing numeral systems and writing in your user\u2019s language and region. Ideally, show them their local default calendar.<\/li>\n<\/ul>\n<p>Alright, we hope you\u2019ve enjoyed this guide to date and time localization and learned a thing or two. Happy coding.<\/p>\n<p><!-- notionvc: bbc8d9a4-7679-40f9-b6b8-c8c5fb694b6b --><\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>We shed light on the intricacies of global dates and times, covering formatting, time zones, regional calendars, and more.<\/p>\n","protected":false},"author":41,"featured_media":39386,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_stopmodifiedupdate":false,"_modified_date":"","_searchwp_excluded":"","footnotes":""},"categories":[40],"class_list":["post-76145","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-localization"],"acf":[],"_links":{"self":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts\/76145"}],"collection":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/comments?post=76145"}],"version-history":[{"count":12,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts\/76145\/revisions"}],"predecessor-version":[{"id":76655,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/posts\/76145\/revisions\/76655"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/media\/39386"}],"wp:attachment":[{"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/media?parent=76145"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/phrase.com\/wp-json\/wp\/v2\/categories?post=76145"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}