Date and time localization is an important topic to consider when it comes to developing applications and software systems in multiple languages. Depending on the country, date and time formats might vary. In this article, we are going to discuss some of the methods that make the date and time localization process easier.
Introduction
It’s no secret that people in different countries might write the date and time in a certain way. For instance, in the US, they specify the month first, followed by the day, and then the year. Each component is also separated with a slash in shortened dates, which gives us mm/dd/yyyy
; for example, 09/01/2021
, which would be September 1, 2021. However, if you show this date to a person from, say, Russia, they would think that 09
is the day and the 01
is the month. That’s because, in CIS countries, the day goes before the month and usually each component is separated with a dot, i.e., dd.mm.yyyy
. Residents of some Asian countries, including Iran, write the year first, followed by the month, and then the day: yyyy/mm/dd
.
Moreover, we have different time formats; some countries tend to use a 12-hour format and append am/pm
, whereas in others the standard is the 24-hour format. Therefore, it’s very important to properly localize date and time based on the currently set locale.
Date and time localization in Python
To work with date and time in Python, you can take advantage of the built-in module called — you guessed it — datetime.
You can import it in the following way:
from datetime import datetime
Creating datetime objects
Now you can easily get the current local date and time in the following way:
currentTime = datetime.now() print(currentTime)
The output will look something like this: 2023-10-24 16:11:39.824903
.
Alternatively, you can create a datetime object based on a string:
specificTime = datetime.fromisoformat('2011-11-04T00:05:23') print(specificTime) # => 2011-11-04 00:05:23
You can take a POSIX timestamp, provide a timezone, and create a datetime object in the following way:
from datetime import datetime, timezone specificTime = datetime.fromtimestamp(1698153639, timezone.utc) print(specificTime) # => 2023-10-24 13:20:39+00:00
The timestamp is basically the number of seconds that have passed since the beginning of the Unix epoch (1 January 1970).
In the example above, we use the UTC time zone. Please note that the timezone
should be imported from the datetime
module as well.
Formatting datetime objects
So, now we know how to create datetime objects with Python. The next question is: how do we format them?
Perhaps the most common method to format date and time in Python is strftime
. It accepts a formatting pattern that, in turn, contains special codes. There are numerous formatting codes available, which you can find in the official documentation.
For example, let’s display the current year, month name, and day, as well as hours and minutes. To achieve this, use the following pattern:
currentTime = datetime.now() print(currentTime.strftime("%Y %B %d, %H:%M"))
The output will look like this: 2023 October 24, 16:27
.
So, what’s going on here?
%Y
means “year”.%B
— the month’s full name based on the currently set locale. Basically, it means that depending on the currently chosen language of your system, the output will vary. We’ll talk about locales later.%d
— zero-padded day of the month. Zero padded means that if the day contains only a single integer, it will be prefixed with zero, e.g.,01
,09
,12
,31
.%H
— hour, zero-padded, 24-hour format.%M
— minute, zero padded.
You can use any formatting codes to display as many details as needed.
Working with locales
Now let’s see how to work with different locales in our Python apps. To achieve this, we’ll need to import the locale
module:
import locale
Next, let’s switch the current locale to ru_RU
and display the current date and time again:
locale.setlocale(locale.LC_ALL, 'ru_RU.UTF8') currentTime = datetime.now() print(currentTime.strftime("%Y %B %d, %H:%M"))
In this case, the month name will be properly localized for us.
Here’s the output: 2023 Октябрь 24, 17:09
.
Great job!
Date and time localization in Java
DateFormat class
First of all, let’s see how to format the time and date in Java. To do this, we can use the DateFormat
. class and then the parse
method.
Here’s an example:
DateFormat shortDateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US); String s = "27/01/1997"; try { Date date = shortDAteFormat.parse(s); System.out.println(date); } catch (ParseException e) { System.out.println("Cannot parse the string!"); }
Here we have used the date instance in the format of DateFormat.SHORT
and provided the US
locale code.
Here’s the output: Mon Jan 27 00:00:00 IST 1997
.
There are other date formats available, such as LONG
, FULL
, and so on.
SimpleDateFormat class
You can also use the SimpleDateFormat
class to quickly parse your date and time, like so:
import java.text.SimpleDateFormat; DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); System.out.println(dateFormat.parse("01/02/1997"));
Here’s the output: Sat Feb 01 00:00:00 IST 1997
.
Likewise, you can call the format
method in the following way:
SimpleDateFormat formatter = new SimpleDateFormat("MM-dd-yyyy"); String date = formatter.format(new Date()); System.out.println(date);
Time zones
Next, let’s talk about time zones in Java. In Java 8, the time zone details are handled by the ZonedDateTime
class. In this class, the time zone is indicated as the number of hours.
You can take the current existing time zone by using the now()
function in the ZonedDateTime
class as follows:
System.out.println(ZonedDateTime.now());
Here’s the output: 2021-07-20T00:02:03.232139+05:30[Asia/Colombo]
.
You can create a new zoned datetime by using the of()
method which accepts the year, month, date, hour, minute, second, nanosecond, and time zone details.
For instance:
ZonedDateTime.of( 2021, 11, 4, 10, 25, 20, 30000, ZoneId.systemDefault() );
Here we have set the time zone using the ZoneId.systemDefault()
method.
TimeZone
is another class for handling time zones in Java. Let’s see how to set and get time zones in Java with the TimeZone
Java class.
First, you need to import the time zone package as follows:
import java.util.TimeZone;
Now let’s move on to the implementation:
Date now = new Date(); TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); System.out.println(now); TimeZone.setDefault( TimeZone.getTimeZone("UTC")); System.out.println(now); TimeZone.setDefault( TimeZone.getTimeZone("GMT")); System.out.println(now);
Here, we have:
- Obtained the current date and time with time zone.
- Got the current time in different time zones by providing the actual time zone.
Here are the outputs:
Mon Jul 19 21:29:22 BST 2021
Mon Jul 19 20:29:22 UTC 2021
Mon Jul 19 20:29:22 GMT 2021
LocalDate class
LocalDate
is another important class introduced in Java 8. This class is immutable and thread safe. Furthermore, LocalDate
represents the date in ISO format, for instance: 2021-01-01
. So let’s see how to perform localization with the Java LocalDate
class.
You can get the current date using the now()
function in the LocalDate
class:
LocalDate currentDate = LocalDate.now();
You can also use the parse()
method to get an instance of the LocalDate
class. You’ll need to provide a parsable string as input and then the parse
function will return the local date and time:
LocalDate.parse("2020-01-21");
A special feature of this class is that it can perform several date-related calculations with built-in functions, such as plusDays()
and minus()
, with ease. Let’s see some examples.
With the plusDays()
function, you can get a future day by adding a certain number of days to a given date. Check out the following example for a better understanding:
LocalDate twoDaysFromToday = LocalDate.now().plusDays(2); System.out.println("Two days from today: " + twoDaysFromToday);
Here’s the output: Two days from today: 2021:08:05
.
To subtract time from a given date, use the minus()
function. In the example below, we’ll return the date from two months prior to today:
LocalDate somePreviousDay = LocalDate.now().minus(2, ChronoUnit.MONTHS);
Moreover, we can easily get a specific day of the week and the first day of the month, and check whether a given year is a leap year:
import java.time.*; import java.time.temporal.TemporalAdjusters; public class Main { public static void main(String[] args) { DayOfWeek day = LocalDate.parse("2021-02-11").getDayOfWeek(); LocalDate firstDayOfMonth = LocalDate.parse("2021-03-30").with(TemporalAdjusters.firstDayOfMonth()); boolean leapYearCheck = LocalDate.parse("2021-02-11").isLeapYear(); System.out.println("day : " + day); System.out.println("firstDayOfMonth : " + firstDayOfMonth); System.out.println("leapYearCheck : " + leapYearCheck); } }
Here’s the output:
day : THURSDAY firstDayOfMonth : 2023-03-01 leapYearCheck : false
So as you see, there are several methods for localizing date and time in Java. Next, we’ll discover how to handle date and time localization in JavaScript.
Date and time localization in JavaScript
Creating datetime objects
The simplest way to create a datetime object is by instantiating the Date
class:
const currentDateTime = new Date(); console.log(current);
Here’s the output: Tue Oct 24 2023 17:16:51 GMT+0300 (Eastern European Summer Time)
.
By default, it simply gets the current local date and time, but you can provide a specific timestamp as well:
const dateTime = new Date(1698157119973); console.log(dateTime);
Here’s the output: Tue Oct 24 2023 17:18:39 GMT+0300 (Eastern European Summer Time)
.
In contrast to some other systems, the timestamp is the number of milliseconds (not seconds) that have passed since the beginning of the Unix epoch.
Instead of passing a timestamp, you can provide a datetime string in the following way:
const dateTime = new Date("2020-02-20T12:00:00Z"); console.log(dateTime);
Output: Thu Feb 20 2020 14:00:00 GMT+0200 (Eastern European Standard Time)
.
It’s not mandatory to provide the time, though — you can pass the date alone:
const dateTime = new Date("2020-02-20"); console.log(dateTime);
Output: Thu Feb 20 2020 02:00:00 GMT+0200 (Eastern European Standard Time)
.
.toLocaleDateString() method
Date.prototype.toLocaleDateString()
is a very convenient method that returns a string with a language-sensitive representation of the date portion of the specified date in the user agent’s time zone.
In other words, it can be used to easily localize the date and time. For instance:
const dateTime = new Date(); const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; console.log(dateTime.toLocaleDateString('de-DE', options)); console.log(dateTime.toLocaleDateString('ru-RU', options)); console.log(dateTime.toLocaleDateString(undefined, options));
In this example, we get the current date and time and then prepare some options for the toLocaleDateString()
method. Then, we display the localized date and time for the de-DE
and ru-RU
locales.
Here are the first two outputs:
Dienstag, 24. Oktober 2023 вторник, 24 октября 2023 г.
If you don’t provide any locale to the toLocalDateString()
function, a default locale will be utilized. Since my current default locale is en-US
, the third output looks like this: Tuesday, 24 October 2023
.
Intl.DateTimeFormat()
Intl.DateTimeFormat()
is yet another object that enables us to format and localize date and time.
Let’s see an example:
const date = new Date(Date.now()); console.log(new Intl.DateTimeFormat('en-US').format(date)); console.log(new Intl.DateTimeFormat(['ban', 'id']).format(date)); console.log(new Intl.DateTimeFormat('ru-RU', { dateStyle: 'full', timeStyle: 'long' }).format(date));
In the first output we simply localize the date and time using the en-US
locale: 10/24/2023
.
Then, we provide a fallback language (Indonesian, id
) in case the requested locale (Balinese, ban
) is not available: 24/10/2023
.
Finally, we use the ru-RU
locale and adjust the formatting options: вторник, 24 октября 2023 г. в 17:35:48 GMT+3
.
There are many other options that you can make use of to format date and time according to your needs.
Date and time localization in PHP
Date function
Next, let’s see how to deal with date and time localization in PHP. To format date and time, you can use the date()
function. It accepts a format and an optional POSIX timestamp. The format is basically a pattern with formatting codes that explains how exactly the date and time should be represented. If the timestamp is not provided, the current date and time are utilized.
For example, let’s display the current day, month, and year:
<?php $today_date = date("d/m/Y"); echo $today_date;
In this case the output will look like this: 24/10/2023
.
Of course, we can format time as well:
<?php echo date("F d, Y h:i:s A");
The output is: October 24, 2023 04:27:08 PM
.
Please refer to the official documentation to learn about other supported formatting characters.
IntlDateFormatter class
You can also utilize the IntlDateFormatter
, and specifically the format
method, to perform even more complex operations.
In this example, we provide the de-DE
locale and the time zone, and use the Gregorian calendar:
<?php $fmt = datefmt_create( 'de-DE', IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'America/Los_Angeles', IntlDateFormatter::GREGORIAN ); echo datefmt_format($fmt, 0);
We then pass 0
as the timestamp (which corresponds to the beginning of the Unix epoch). The output will look like this: Mittwoch, 31. Dezember 1969 16:00 Uhr GMT-08:00
.
Date and time localization in Ruby on Rails
To properly localize date and time in Ruby on Rails, use the localize
method aliased as l
. Adding the rails-i18n gem into the Gemfile
that has the locale data for the different languages is also recommended. For example, it has translated month names, pluralization rules, and other useful stuff.
The l
method is very similar to Ruby’s strftime
. You can provide a predefined format or construct your own.
For instance, here’s how to use the :long
format:
l post.created_at, format: :long
Depending on the locale, this format will be a bit different but in general, it displays your date and time in the following way: “full month name – day – year – hours – minutes.”
Here’s the sample output: January 23, 2021 23:05
.
You can also specify your very own format:
l post.created_at, format: "%B %Y"
The placeholders are similar to the ones listed in the strftime
docs.
On top of that, you can create custom formats in your translation files. To achieve this, open a translation file inside the config/locales
folder and add something like this:
en: time: formats: very_short: "%H:%M"
Now you have a very_short
format available for the English locale. It’s important to define the new format for all other locales as well.
To learn more about the general Rails internationalization and localization process and how to add a locale switcher to your app, you can check out our step-by-step tutorial.
Summary
So, in this article, we’ve discussed how to handle date and time localization in several programming languages such as Python, PHP, Java, JavaScript, and Ruby. If you’d like to learn more about i18n and l10n processes in various technologies, you might be interested in checking out our collection of tutorials which lists how-tos for many popular languages and technologies.
Thank you for staying with me and happy coding!