JavaRush /Java Blog /Random EN /An intuitive, robust library for working with times and d...
theGrass
Level 24
Саратов

An intuitive, robust library for working with times and dates is finally available in Java (Part 2).

Published in the Random EN group
Times of Day
    So let's move on. The next entity after date is the time of day, represented by the LocalTime class . A classic example is representing the opening hours of a store, say from 7:00 to 23:00. Stores open at this time across the country, but actual times will vary depending on time zone.     LocalTime is a value class that stores only time, without an associated date or time zone. When adding or subtracting a time period, it will be cut off at midnight. That is, 20:00 plus 6 hours is 2:00. Using LocalTime is similar to LocalDate : LocalTime time = LocalTime.of(20, 30); int hour = date.getHour(); // 20 int minute = date.getMinute(); // 30 time = time.withSecond(6); // 20:30:06 time = time.plusMinutes(3); // 20:33:06     Modifiers can work with LocalTime , but time operations are usually not so complex that modifiers are required.
Combining date and time
    The next class we'll look at is LocalDateTime . This value class is a combination of LocalDate and LocalTime . It represents both date and time, without a time zone.      LocalDateTime can be created either directly or by combining date and time: LocalDateTime dt1 = LocalDateTime.of(2014, Month.JUNE, 10, 20, 30); LocalDateTime dt2 = LocalDateTime.of(date, time); LocalDateTime dt3 = date.atTime(20, 30); LocalDateTime dt4 = date.atTime(time);     The third and fourth options use the atTime() method , which provides a flexible way to combine date and time. Most date and time system classes have "at" methods that can be used when combining your object with another to create a more complex one. The other methods of the LocalDateTime class are similar to those of LocalDate and LocalTime . Similar method naming patterns make the API easier to learn . This table lists all involved method prefixes: An intuitive, robust library for working with times and dates is finally available in Java (Part 2).  - 1
Instant
    When we deal with dates and times, we usually work with years, months, days, hours, minutes, seconds. However, this is only one model of time that can be called “human”. The second model commonly used is “machine” or “continuous” time. In this model, a point on the time axis is represented by one large number. This approach simplifies the calculation algorithms, and is used to store time in the Unix operating system , where time is represented by the number of seconds that have passed since January 1, 1970. Similarly, in Java , time is stored as the number of milliseconds that have passed since January 1, 1970. The machine approach to time calculations in the java.time API is provided by the Instant value class . It provides the ability to represent a point on a time axis without all the accompanying information, such as time zone. In fact, this class contains the number of nanoseconds that have passed since midnight on January 1, 1970. Instant start = Instant.now(); // произведем вычисления Instant end = Instant.now(); assert end.isAfter(start); //машина времени не сработала     Typically the Instant class is used to store and compare points in time when you need to store when some event happened but you don't care about the time zone in which it happened. In most cases, it's more interesting what we can't do with the Instant class than what we can do with it. For example, the following lines of code will throw exceptions: instant.get(ChronoField.MONTH_OF_YEAR); instant.plus(6, ChronoUnit.YEARS);     Exceptions occur because the instant object only stores the number of nanoseconds and does not provide the ability to work with units of time that are more useful to humans. To use other units of measurement, you must at least specify a time zone.
Time Zones
    The principle of time zones was developed in England when the invention of railroads and improvements in other means of communication allowed people to travel distances sufficient for differences in solar time to be noticeable. Until this time, each village and city lived according to its own time, which was most often measured by sundial. This picture shows an example of the difficulties this led to - the red hands on the clock show Greenwich time, and the black hands show local time, which differs by 10 minutes: The time An intuitive, robust library for working with times and dates is finally available in Java (Part 2).  - 2     zone system developed, replacing local solar time. But the key fact is that time zones are created by politicians, and are often used to demonstrate political control over an area. Like any policy, rules related to time zones often defy logic. And also, these rules can change, and often change, without any warning. Time zone rules are compiled by an international group that publishes the IANA Time Zone Database . It contains the identifier of each region of the Earth, and the history of time zone changes for it. The identifiers look like “Europe/London” or “America/New_York” . Before the java.time API was released, the TimeZone class was used to represent a time zone . Now ZoneId is used instead . There are two key differences between them. First, ZoneId is immutable, which makes it possible to store objects of this class in static variables, among other things. Secondly, the rules themselves are stored in the ZoneRules class , and not in the ZoneId itself , and to get them you need to call the getRules() method on the ZoneId class object . A common feature of all time zones is a fixed offset from UTC/Greenwich . Most often you use this when talking about time differences between different cities, such as "New York is 5 hours behind London." The ZoneOffset class , a descendant of ZoneId , represents the time difference with the prime meridian passing through Greenwich in London. From a developer's point of view, it would be great to not have to deal with time zones and their complexities. The java.time API allows you to do this as long as it is possible. Wherever possible, use the LocalDate, LocalTime, LocalDateTime and Instant classes . Where you cannot do without time zones, use the ZonedDateTime class . ZonedDateTime class allows you to convert dates and times from human units of measurement, which we see on calendars and watches, to machine units. As a result, you can create a ZonedTimeDate either from the Local class or from the Instant class : ZoneId zone = ZoneId.of("Europe/Paris"); LocalDate date = LocalDate.of(2014, Month.JUNE, 10); ZonedDateTime zdt1 = date.atStartOfDay(zone); Instant instant = Instant.now(); ZonedDateTime zdt2 = instant.atZone(zone);     One of the most unpleasant features of time zones is the so-called daylight saving time. With Daylight Saving Time switching to and from Greenwich, your time zone difference with Greenwich changes twice (or more) a year, usually increasing in the spring and decreasing in the fall. When this happens, we have to change all the clocks in our house. In the java.time classes , offset data is represented as "offset transforms" . In the spring this causes a “gap” in time, when some time values ​​are impossible, and in the fall, on the contrary, some time values ​​occur twice. All of this is supported by the ZonedDateTime class through its factory methods and converter methods. For example, adding one day adds a logical day, which can be represented by more or less than 24 hours if we switch to daylight saving time or back. Likewise, the atStartOfDay() method is named so because we cannot guarantee that the day will start exactly at midnight - we must take into account the time gap when switching to daylight saving. And one last tip regarding daylight saving time. If you want to demonstrate that you have accounted for time overlap during the transition from summer to winter (when the same time value appears twice), you can use one of two special methods designed for such situations: These methods will return the earlier or later zdt = zdt.withEarlierOffsetAtOverlap(); zdt = zdt.withLaterOffsetAtOverlap();     value , if the object gets caught in an overlap during the transition from summer to winter time. In all other situations, the return values ​​will be the same.
Time intervals
    All the classes we discussed earlier work as points on the timeline. Two additional value classes are needed to represent time intervals. The Duration class represents a length of time, measured in seconds and nanoseconds. For example, “23.6 seconds.” The Period class represents a period of time measured in years, months, and days. For example - “3 years, 2 months and 6 days.” These intervals can be added or subtracted from a date or time: Period sixMonths = Period.ofMonths(6); LocalDate date = LocalDate.now(); LocalDate future = date.plus(sixMonths);
Formatting and parsing
    An entire package is designed to format and display dates and times - java.time.format . The package revolves around the DateTimeFormatter class and its DateTimeFormatterBuilder factory . The most common ways to create a formatter are through static methods and constants in DateTimeFormatter , including:
  • Constants for common formats described in ISO, such as ISO_LOCAL_DATE.
  • Patterns identified by letters, such as ofPattern("dd/MM/uuuu").
  • Localized styles such as ofLocalizedDate(FormatStyle.MEDIUM).
    Once you've created a formatter, you typically use it by passing it to the appropriate date class method: DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/uuuu"); LocalDate date = LocalDate.parse("24/06/2014", f); String str = date.format(f);     This way, the code responsible for formatting the date output is isolated into a separate class. If you need to separately specify the locale for date formatting, use the withLocale(Locale) formatter method . The classes responsible for the calendar, time zone, and input/output of fractional numbers have similar methods. If you need more fine-tuning options, see the documentation for the DateTimeFormatterBuilder class , which allows you to create complex formatters step by step. It also allows you to set case-insensitive text parsing, ignore some parsing errors, set offsets and optional elements.
Bottom line
     The java.time API is a new comprehensive model for working with date and time in Java SE 8 . It takes the ideas and implementations from Joda-Time to the next level and finally allows developers to avoid using java.util.Date and Calendar . Now working with dates and times can be fun!      Original article
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION