Java 8 - Part II [Localization, Date, Time]
Hello, everybody!!!
This post is the second subject of the series about the changes that you can find between version 6 to 8. Here we will talk about the Localization.
Summary
Advantages of localizing and how to define, read, and set the locale
Some attributes as Language, Dates, Times, Numbers, Currencies or Messages will vary from one region to another. The application needs to be prepared for this. And it is the Internationalization proposition and Localization. More detail can be seen here.
Internationalization is the process of designing your program to support more than one language or country. Internationalization just means that you can.
Localization means actually supporting multiple locales. You can think of a locale as being like a language and country pairing.
Resource Bundle
The first step in internationalization is to do a map to translate text into ResourceBundle objects. The map is a collection of key/value pairs.
It can be possible using property files or a java class (used when you need not only String). Who handles this is the Resource Bundles with abstract class java.util.ResourceBundle. If the application use property files to represent locale, then it's necessary to use the subclass java.util.PropertyResourceBundle. If the application uses Java Class to represent locale, java.util.ListResourceBundle. Java class has to have the same name that you would use for a property file.
Steps used by java to find the bundle:
- Java first searches for a bundle whose name matches the complete locale:
package.bundle_language_country_variant
- If it cannot find one, it drops the last component of the name and repeats the search:
package.bundle_language_country
- If it cannot find one, again, it drops the last component of the name and repeats the search:
package.bundle_language
- If still cannot find one, the last component is dropped again, leaving just the name of the bundle:
package.bundle
- If nothing is found, a
MissingBundleException
is thrown. - If a class and a property file share the same name, Java gives priority to the class.
Create and manage date- and time -based events
The Java 8 version try to improve the use of date and time. Some limitations as months start at '0' (java.util.Date) or java.util.Date and java.util.Calendar be immutable class could come out problems in some applications.
Then, this version introduced a new API to support those aspects. That API brought new classes that are immutable and thread-safe:
- Classes that implement the interface java.time.temporal.Temporal:
- LocalDate: represents a year, month, and day. Obs: Months start at '1'. It's possible to create, to get, compare or manipulate values (adding or subtracting). Examples here.
- LocalTime: hour, minutes, seconds, and nanoseconds. It's possible to create, to get, compare or manipulate values (adding or subtracting). Examples here.
- LocalDateTime: A combination of the above. It's possible to create, to get, compare or manipulate values (adding or subtracting). Examples here.
- Instant: It is a point in time represented by a single point in time in seconds and nanoseconds. It's possible to get, compare or manipulate values (adding or subtracting). OBS: You cannot convert a LocalDateTime to an Instant. Obs: Instant displays a year and month but you cannot do math with those fields.
- LocalDate: represents a year, month, and day. Obs: Months start at '1'. It's possible to create, to get, compare or manipulate values (adding or subtracting). Examples here.
Resource: java-8-tips
- Classes that implement the interface java.time.temporal.TemporalAmount:
- Period: Represents an amount of time in terms of years, months and days. It's possible to create, to get and to identify a period between two LocalDates. The results can be negative values. OBS: You cannot chain methods when creating a Period. You will get a compiler warning about this. Examples here.
- Duration: It is as a Period represented by an amount of time in terms of seconds and nanoseconds. It's possible to create, to get, to identify a difference between two Temporal types (LocalTime, LocalDateTime and Instant) or manipulate values. Examples here.
Reference: Oracle Certified Professional Java SE 8 Programmer Exam 1Z0-809
The objects created by these classes are immutable. For this reason, Java added a with method to create another object from an existing one. For example, you can create a new LocalDate using .withMonth(12).withDayOfMonth(25).
For adding or subtracting methods you can use the specific methods or the generic method. An example of a specific method is from LocalDate, object.minusYears(2). If you choose the generic way, you will do object.minus(2, ChronoUnit.YEARS).
In the same way, to get a specific information related with the created object you can use a specific get method or you can use a generic get method. Then, to get a year in a LocalData, for example, you can use object.getYear() or object.get(ChronoField.YEAR).
The possible values to ChronoField and ChronoUnit are different to each class. Observe that Period and Duration don’t use these enums.
ChronoField
LocalDate | LocalTime | LocalDateTime | Instant |
---|---|---|---|
ChronoUnit
Examples of different ways to use the date in the versions.
Old Version | J8 |
---|---|
import java.util.*; | import java.time.*; |
Calendar c = new GregorianCalendar(2018, Calendar.JANUARY, 1); | |
Date jan = c.getTime(); | LocalDate jan = LocalDate.of(2018, Month.JANUARY,1); |
public Date addDay(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.DATE, 1); return cal.getTime(); } | public LocalDate addDay(LocalDate date) { return date.plusDays(1); } |
public Date subtractDay(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.DATE, -1); return cal.getTime(); } | public LocalDate subtractDay(LocalDate date) { return date.minusDays(1); } |
Format Numbers and currency
To format numbers you will use NumberFormat class and use format() method to turn a number into a String and parse() method to turn a String into a number.
Format Date and Time
You can use java.time.format.DateTimeFormatter to read or print in different formats. When use method toString() to print the value, the formats will be:
- LocalDate: uuuu-MM-dd
- LocalTime: HH:mm:ss.SSSSSSSSS
- LocalDateTime: uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSS
- Instant: uuuu-MM-dd'T'HH:mm:ss.SSSSSSSSS
- Period: PNYNMND
- Duration: PTnHnMnS
If you want to customize the format you should use the ofPattern() method in the DateTimeFormatter class. Pay attention in UPPERCASE and lowercase letters. In dd-MM-yy, MM refers to month. In dd-mm-yy, mm refers to minutes.
To format the time you can follow the same idea.
To parse date you can use SHORT date format.
Time zones
To work with the zone, the new version changes the use from TimeZone class to ZonedDateTime, where (as you can guess) you have the date, time and zone. For example, "10:50 a.m. EST". Time zone is expressed as a number of hours
The new class have new options:
- ZoneID: America/Fortaleza
- ZoneOffset: -03:00 (or UTC+11:00) (It has to be started with a sign)
- ZonedDateTime: 2018-11-28T20:30:43.274-03:00[America/Fortaleza]
- OffsetDateTime: 2018-11-28T20:30:43.274-03:00.
- OffsetTime: 20:30:43.274-03:00
Posts Related
- Java 8 - Part VII [Collections]
- Java 8 – Part VI [File IO NIO.2]
- Java 8 – Part V [Concurreny]
- Java 8 – Part IV [Streams]
- Java 8 – Parte III [Lambda]
- Java 8 - Part II [Localization, Date, Time]
- Java 8 - Language Enhancements
- JVM
Reference
- GitHub: Localization Examples
- OCP8: Localization
- OCP8: Date and Time
- OCP8: zone
- A beginner's guide to Java Internationalization
- Oracle Certified Professional Java SE 8 Programmer Exam 1Z0-809