Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Java time to operate class library Joda-Time

2025-02-03 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article focuses on "how to use Java time to operate the class library Joda-Time", interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let the editor take you to learn "how to use Java time to operate the class library Joda-Time"!

Time class library in previous versions of JDK8

1.1 defects and deficiencies of the original time class library

When we use pre-Java8 class libraries, we are always unhappy when dealing with date-time, including but not limited to the following slot points:

In Java version 1. 0, the operation on time and date is completely dependent on the java.util.Data class, and time can only be represented with millisecond precision, but not date.

There are great defects in ease of use. The starting time of the year is 1900 and the month starts at 0.

The value returned by the toString method is not intuitive and has a time zone.

In the Java1.1 version, many methods in many Date classes have been discarded and java.util.Calendar has been added. But like Date, Calendar classes have similar problems and design flaws, making it easy to make mistakes in code written using these classes.

The month is still calculated from 0.

The commonly used date and time operations need to use Date, Canendar and SimpleDateFormat at the same time, which is more tedious.

Some features exist only in one class (DateFormat methods that parse and format a date or time only exist in the Date class).

DateFormat is not thread-safe, and if two threads try to resolve a date using the same formatter, you may get unexpected results.

Both Date and Canendar are mutable.

1.2 reasons for SimpleDateFormat thread unsafety

Because the contribution variable calendar used by the parse method is not thread-safe. The calendar assignment is carried out in the format (subFormat) method, and it is worth dealing with in the parse, so in the case of concurrency, the calendar cleanup is not timely and the value is overwritten.

/ * * The {@ link Calendar} instance used for calculating the date-time fields * and the instant of time. This field is used for both formatting and * parsing. * *

Subclasses should initialize this field to a {@ link Calendar} * appropriate for the {@ link Locale} associated with this * DateFormat. * @ serial * / protected Calendar calendar; @ Override public StringBuffer format (Date date, StringBuffer toAppendTo, FieldPosition pos) {pos.beginIndex = pos.endIndex = 0; return format (date, toAppendTo, pos.getFieldDelegate ();} / Called from Format after creating a FieldDelegate private StringBuffer format (Date date, StringBuffer toAppendTo, FieldDelegate delegate) {/ / Convert input date to time field list calendar.setTime (date) / / At this point the fields of Calendar have been set. Calendar / / will fill in default values for missing fields when the time / / is computed. Pos.index = start; Date parsedDate; try {parsedDate = calb.establish (calendar). GetTime (); / / If the year value is ambiguous, / / then the two-digit year = = the default start year if (ambiguousYear [0]) {if (parsedDate.before (defaultCenturyStart)) {parsedDate = calb.addYear (100) .establishment (calendar). GetTime () }

1.3 how to solve the above thread unsafe problem?

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Use ThreadLocal to create a thread-specific SimpleDateFormat variable for each thread

Create local variables when needed

Use org.apacle.commons.lang3.time.DateFormatUtils

Use Joda-Time (described later)

II. Joda-Time date and time class library

2.1 introduction

Joda-Time is a high-quality date and time development library provided by Joda outside of JDK, which follows the Apache2.0 open source protocol.

Joda projects other than Joda-Time include Joda-Money, Joda-Beans, Joda-Convert and Joda-Collect Joda official websites.

2.1.1 Why use Joda-Time

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Easy to use: Calendar is difficult to access "normal" dates and lacks simple embalming. Joda-Time has simple field access, such as getting getYear () for the year and getDayOfWeek () for the day of the week.

Easy to extend: JDK supports the use of subclasses to implement multiple calendar systems, but this is very cumbersome, and it is difficult to choose another calendar system in the implementation. Joda-Time supports the implementation of multiple pluggable calendar systems based on Chronology classes.

Full-featured: Joda-Time provides all the necessary functions for date and time calculations, providing out-of-the-box features.

The latest time zone calculation: the implementation of the time zone is based on the common time zone information database and is updated several times a year. The new version of Joda-Time includes all the changes to this database, and the necessary updates should be made as soon as possible. It is easy to update the zone data manually.

Calendar support: 8 calendar systems are provided.

Interoperability: internally identified in milliseconds, which is consistent with JDK or other public time representations.

Good performance: support minimal computing for all accessed domains.

Good test coverage: there are all-round testers to ensure the quality of the library,

Complete documentation: there is a complete user guide that provides an overview of common usage scenarios. Javadoc is very detailed and covers the rest of API.

Development: actively developed since 2002, it is a mature and reliable code base, and some related projects are currently available.

Open source: released under the Apache 2.0 open source protocol.

2.1.2 key benefits of Joda-Time

LocalDate: contains only dates

LocalTime: contains only time

Instant: point in time on the Timelin

DateTime: the complete date and time in the time zone

DateTimeZone: better time zone

Duration and Period: duration

Interval: the time between two time points

Comprehensive and flexible time formatting and conversion

Because Joda-Time has so many advantages over the pre-Java8 time class library, Joda-Time has become the de facto standard Java date and time library.

2.2 feature interpretation

2.2.1 Interoperability between Joda-Time and JDK

Interoperability means that the Joda class can generate instances of java.util.Date (and Calendar), which allows us to retain our existing dependency on JDK while using Joda to handle complex date / time calculations.

Date To Joda-Time

Date date = new Date (); DateTime dateTime = new DateTime (date)

Canendar To Joda-Time

Calendar calendar = Calendar.getInstance (); DateTime dateTime = new DateTime (calendar)

Joda-Time To Date

Date date = new Date (); DateTime dateTime = new DateTime (date); Date date2 = dateTime.toDate ()

Joda-Time To Calendar

Calendar calendar = Calendar.getInstance (); dateTime = new DateTime (calendar); Calendar calendar2 = dateTime.toCalendar (Locale.CHINA)

2.2.2 understanding of key date / time concepts in Joda

Joda uses the following concepts so that they can be applied to any date / time library:

Immutability (Immutability)

Joda-Time is similar to java.lang.String in that its instances cannot be modified (because any operation that changes its value generates a new object), which means that they are thread-safe.

Transient (Instant)

As indicated in the interface org.joda.time.ReadableInstant, Instant represents a precise point in time, the number of milliseconds calculated from epoch:1970-01-01T00:00:00Z, which is also designed to make its subclasses compatible with JDK Date and Calendar classes.

/ * Defines an instant in the datetime continuum. * This interface expresses the datetime as milliseconds from 1970-01-01T00:00:00Z. *

* The implementation of this interface may be mutable or immutable. * This interface only gives access to retrieve data, never to change it. *

* Methods in your application should be defined using ReadableInstant * as a parameter if the method only wants to read the instant without needing to know * the specific datetime fields. *

* The {@ code compareTo} method is no longer defined in this class in version 2.0. * Instead, the definition is simply inherited from the {@ code Comparable} interface. * This approach is necessary to preserve binary compatibility. * The definition of the comparison is ascending order by millisecond instant. * Implementors are recommended to extend {@ code AbstractInstant} instead of this interface. * * @ author Stephen Colebourne * @ since 1.0 * / public interface ReadableInstant extends Comparable {/ * Get the value as the number of milliseconds since * the epoch, 1970-01-01T00:00:00Z. * * @ return the value as milliseconds * / long getMillis ();}

Locality (Partial)

Transient expression is a precise moment in time relative to epoch, while a local time refers to a part of time that can be changed in some ways (essentially generating a new class), so that it can be used in many places as a point in the repetition cycle.

Chronology (Chronology)

The core of Joda-Time design is org.joda.time.Chronology. Basically, chronology is a calendar system, a special way to calculate time, and a framework in which calendar algorithms are executed. The eight chronologies supported by Joda-Time are as follows:

ISO (default)-org.joda.time.chrono.ISOChronology

GJ-org.joda.time.chrono.GJChronology

Gregorian-org.joda.time.chrono.GregorianChronology

Julian-org.joda.time.chrono.JulianChronology

Coptic-org.joda.time.chrono.CopticChronology

Buddhist-org.joda.time.chrono.BuddhistChronology

Ethiopic-org.joda.time.chrono.EthiopicChronology

Islamic-org.joda.time.chrono.IslamicChronology

Each of the above chronologies can be used as a computing engine for a specific calendar system and is a pluggable implementation.

Time zone (Time zone)

The specific definition is explained in the encyclopedia. In the actual coding process, any strict time calculation must involve the time zone (or relative to GMT). The corresponding core class in Joda-Time is org.joda.time.DateTimeZone. Although the operation of the time zone is not involved in daily use, it is worth noting how DateTimeZone affects DateTime.

2.3 specific usage

After introducing some of the concepts of Joda-Time above, we will explain it in detail:

2.3.1 create a Joda-Time object

Transient-ReadableInstant

/ / 1. Use system time DateTime dateTime1 = new DateTime (); / / 2. Use date Date jdkDate1 = new Date () in jdk; DateTime dateTime2 = new DateTime (jdkDate1); / / 3. Specify Date jdkDate2 = new Date (); long millis = jdkDate.getTime (); DateTime dateTime3 = new DateTime (millis) in milliseconds; / / 4. Use Calendar Calendar calendar = Calendar.getInstance (); DateTime dateTime4 = new DateTime (calendar); / / 5. Use multiple fields to specify an instant (local time segment) / / year month day hour (midnight is zero) minute second milliseconds DateTime dateTime5 = new DateTime (2000, 1, 1, 0, 0, 0, 0); / / 6. Generate another DateTime DateTime dateTime6 = new DateTime (dateTime1) from one DateTime; / / 7. Have a time string to generate DateTime String timeString = "2019-01-01T00:00:00-06:00"; DateTime dateTime7 = DateTime.parse (timeString)

Locality-ReadablePartial

When the date or time processed in the program does not need to be a complete time, you can create a local time, such as if you only want to focus on the year / month / day, or the time of day, or the day of the week. These times are represented by the org.joda.time.ReadablePartial interface in Joda-Time, and the two classes that implement it, LocalDate and LocalTime, are used to represent the year / month / day and a certain time of day, respectively.

/ / each field LocalDate localDate = new LocalDate (2019, 1,1) is provided explicitly; / / 6:30:06 PM LocalTime localTime = new LocalTime (18,30,6,0)

LocalDate replaces the org.joda.time.YearMonthDay,LocalTime used in the earlier version of Joda-Time, which replaces the previous version of org.joda.time.TimeOfDay. (all have been marked as obsolete).

Time span

Joda-Time provides three classes to represent time spans (which can be useful in some business requirements).

Duration

This class represents absolute precision in milliseconds and provides a method of standard mathematical transformation while converting the time span to standard units.

Period

This class is expressed in units of year, month and day.

Interval

This class represents a specific time span and uses a clear moment to define the scope of the time span. Interval is a half-open interval, so the time span encapsulated by it includes the start time of the period, but does not include the end time.

2.3.2 processing time using Joda-Time method

DateTime today = new DateTime (); / / get the time before 777 seconds DateTime dateTime1 = today.minus (777 * 1000); / / get the time of tomorrow DateTime tomorrow = today.plusDays (1); / / get the date of the first day of the month DateTime dateTime2 = today.withDayOfMonth (1); / / get the last day of the month three months after the current time DateTime dateTime3 = today.plusMonths (3). DayOfMonth (). WithMaximumValue ()

The following is a partial list of DateTime methods: methods that begin with plus/minus (such as plusDay, minusMonths): used to return instances that have been added or decreased over a period of time on DateTime instances

Plus (long duration) increments the specified number of milliseconds and returns

PlusYears (int years) adds a specified year and returns

PlusMonths (int months) increments the specified month and returns

PlusWeeks (int weeks) increments the specified week and returns

PlusDays (int days) increases the specified number of days and returns

PlusHours (int hours) increases the specified hour and returns

PlusMinutes (int minutes) increases the specified minutes and returns

PlusSeconds (int seconds) increments the specified number of seconds and returns

PlusMillis (int millis) increases the specified milliseconds and returns

On the contrary, the plus of the minus prefix is increasing and minus is decreasing.

Method at the beginning of with: used to return the instance after the DateTime instance updates the specified date unit

WithCenturyOfEra (int centuryOfEra) updates the century unit of time and returns

WithYearOfCentury (int yearOfCentury) updates the century year and returns

WithYear (int year) update time year and return

WithWeekyear (int weekyear) updates the number of weeks and returns

WithMonthOfYear (int monthOfYear) updates the time month and returns

WithDayOfYear (int dayOfYear) updates the number of days and returns

WithDayOfMonth (int dayOfMonth) updates the number of days and returns

WithDayOfWeek (int dayOfWeek) updates the number of days and returns

WithHourOfDay (int hour) updates for hours and returns

WithMinuteOfHour (int minute) update time minutes and return

WithSecondOfMinute (int second) update time seconds and return

WithMillisOfSecond (int millis) update time millisecond and return

WithMillisOfDay (int millis) update time millisecond and return

WithTimeAtStartOfDay () gets the earliest time of the day

Some operation methods for judging the size state of DateTime objects

CompareTo (DateTime d) compare two time size time greater than specified time return 1 time less than specified time return-1 equality return 0

Equals (DateTime d) compares whether the two times are equal

IsAfter (long instant) determines whether the time is longer than the specified time

IsAfterNow () determines whether the time is greater than the current time

IsBefore (long instant) determines whether the time is less than the specified time

IsBeforeNow () determines whether the time is less than the current time

IsEqual (long instant) determines whether the time is equal to the specified time

IsEqualNow () determines whether the time is equal to the current time

2.3.3 format time in Joda-Time

/ / the format template passed in only needs a format string compatible with JDK SimpleDateFormat to public static String convert (Date date,String dateFormat) {return new DateTime (date) .toString (dateFormat);} / / convert Date in JDK to DateTime DateTime dateTime = new DateTime (new Date (), DateTimeZone.UTC) in UTC time zone / / convert String to DateTime public static Date convertUTC2Date (String utcDate) {DateTime dateTime = DateTime.parse (utcDate, DateTimeFormat.forPattern ("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); return dateTime.toDate ();}

For more information on how to use it, please refer to the official documentation.

III. New time class library in JAVA 8

3.1 introduction

Due to the shortcomings and poor experience of the previous version of the JDK class library, coupled with the influence of the standard Joda-Time that has become a reality, Oracle decided to provide high-quality date and time support in JAVA API, that is, the new time library of JDK 8, which integrates most of the Joda-Time features. (the author of Joda-Time actually participated in the development and implemented the whole content of JSR310, and the new API is located under java.time. There are several common classes: LocalDate, LocalTime, Instant, Duration, and Period.)

Because the new time class library of JDK 8 borrows a lot from the design ideas and even naming of Joda-Time, if you are a user of Joda-Time, you can use the new API without learning cost (of course, there are some differences between them to be aware of).

3.2 method of use

3.2.1 using LocalDate and LocalTime

The first is LocalDate, where the instance of this class is an immutable object that provides a simple date and does not contain time information for the day. In addition, it does not carry any information related to the time zone.

/ / create LocalDate LocalDate date = LocalDate.of (2019, 1,1) using the specified date; / / get the current date LocalDate today = LocalDate.now (); / / get today's properties int year = date.getYear (); Month month = date.getMonth (); int day = date.getDayOfMonth (); DayOfWeek dow = date.getDayOfWeek (); int len = date.lengthOfMonth (); boolean leap = date.isLeapYear () / / obtain the required attribute field int year = date.get (ChronoField.YEAR) through the enumerated value of ChronoField

Then there is LocalTime, which represents a certain time of day.

LocalTime time = LocalTime.of (18,18,18); int hour = time.getHour (); int minute = time.getMinute (); int second = time.getSecond ()

Both LocalDate and LocalTime can be created by parsing strings using the static method parse.

LocalDate date = LocalDate.parse ("2019-01-01"); LocalTime time = LocalTime.parse ("18:18:18")

You can also pass a DateTimeFormatter to the parse method, and an instance of this class defines how to format a date or time object. It is actually a substitute for the old version of java.util.DateFormat.

3.2.2 LocalDateTime

/ / directly create LocalDateTime LocalDateTime dt1 = LocalDateTime.of (2019, Month.JANUARY, 1,18,18,18); / / merge date and time LocalDate date = LocalDate.parse ("2019-01-01"); LocalTime time = LocalTime.parse ("18:18:18"); LocalDateTime dt2 = LocalDateTime.of (date, time); LocalDateTime dt3 = date.atTime (18,18,18); LocalDateTime dt4 = date.atTime (time); LocalDateTime dt5 = time.atDate (date) / / extract LocalDate from LocalDateTime or LocalTime LocalDate date1 = dt1.toLocalDate (); LocalTime time1 = dt1.toLocalTime ()

3.3.3 Instant

The Instant class is designed to be easy for computers to understand. It represents a single large integer at a point in a duration period, which is actually calculated by the number of seconds experienced at the beginning of the Unix meta-year (traditionally set to midnight in the UTC time zone, 1970) (the minimum unit of calculation is nanosecond).

/ / pass an instance of this class that has been created in seconds Instant.ofEpochSecond (3); / / pass a second + nanosecond 2 seconds plus 1 million nanosecond (1 second) Instant.ofEpochSecond (2,1000 million)

3.3.4 Duration and Period

Duration is used to compare the time difference between two LocalTime objects or two Instant.

Duration D1 = Duration.between (time1, time2); Duration D1 = Duration.between (dateTime1, dateTime2); Duration D2 = Duration.between (instant1, instant2)

Period is used to compare multiple times in the way of year, month and day.

Period tenDays = Period.between (LocalDate.of (2019, 1,1), lcalDate.of (2019, 2,2))

Of course, both the Duration and Period classes provide a number of very convenient factory classes to create corresponding instances directly.

Duration threeMinutes = Duration.ofMinutes (3); Duration threeMinutes = Duration.of (3, ChronoUnit.MINUTES); Period tenDays = Period.ofDays (10); Period threeWeeks = Period.ofWeeks (3); Period twoYearsSixMonthsOneDay = Period.of (2,6,1)

3.3.5 Operation, parsing and formatting dates

/ / directly use the withAttribute method to modify LocalDate date1 = LocalDate.of (2019, 1, 1); LocalDate date2 = date1.withYear (2019); LocalDate date3 = date2.withDayOfMonth (1); LocalDate date4 = date3.with (ChronoField.MONTH_OF_YEAR, 1)

All classes LocalDate, LocalTime, LocalDateTime, and Instant that declare the Temporal interface use get and with methods to distinguish between reading and modifying object values, and throw a UnsupportedTemporalTypeException exception if an unsupported field is used to access the field. Similarly, both the plus and minus methods are declared in the Temporal interface. Through these methods, we can add or subtract a number from the TemporalUnit object, we can easily backtrack or roll back the Temporal object to a certain period of time, and we can easily implement the TemporalUnit interface through ChronoUnit enumeration.

3.3.6 more customized processing time

Passing a customized TemporalAdjuster object to the overloaded with method provides more flexibility in dealing with dates. The time and date API already provides a large number of predefined TemporalAdjuster, which can be accessed through the static factory method of the TemporalAdjuster class. The names of these methods are very intuitive, and the method name is the problem description. In some cases, if you need to define your own TemporalAdjuster, just declare the TemporalAdjuster interface and implement the corresponding method yourself.

LocalDate date1 = LocalDate.of (2014, 3,18); LocalDate date2 = date1.with (TemporalAdjuster.nextOrSame (DayOfWeek.SUNDAY)); LocalDate date3 = date2.with (TemporalAdjuster.lastDayOfMonth ())

3.3.7 parsing date-time object

Formatting and parsing date-time objects is another very important function in our daily work, and the new java.time.format package is specially designed for this purpose. Of these, the most important class is DateTimeFormatter. All DateTimeFormatter instances can be used to create strings that represent a specific date or time in a certain format. (compared to the old java.util.DateFormat, all DateTimeFormatter instances are thread-safe.)

/ / generate strings using different formatters

LocalDate date = LocalDate.of (2019, 1, 1)

String S1 = date.format (DateTimeFormatter.BASIC_ISO_DATE)

String S2 = date.format (DateTimeFormatter.ISO_LOCAL_DATE)

/ / generate LocalDate object

LocalDate date1 = LocalDate.parse ("20190101", DateTimeFormatter.BASIC_ISO_DATE)

LocalDate date2 = LocalDate.parse (2019-01-01, DateTimeFormatter.ISO_LOCAL_DATE)

/ / create a formatter using a specific pattern DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("dd/MM/yyyy"); LocalDate date1 = LocalDate.of (2019, 1, 1); String formattedDate = date1.format (formatter); LocalDate date2 = LocalDate.parse (formattedDate, formatter)

3.3.8 dealing with different time zones and calendar systems

In the new date-time class library, the new java.time.ZoneId class (like other date and time classes, the ZoneID class is immutable) is used to replace the old java.util.TimeZone in order to minimize the complexity and complexity of dealing with the time zone. The time zone divides the area into the same interval of standard time according to certain rules. There are 40 such instances in the ZoneRules class. You can simply call getRules () of ZoneId to get the rules for the specified time zone. Each specific ZoneId object is identified by a regional ID, and the regional ID is in the format "{region} / {City}". For example:

ZoneId romeZone = ZoneId.of ("Asia/Shanghai")

Java 8 adds a new method, toZoneId, to the original TimeZone to convert an old time zone object to ZoneId:

ZoneId zoneId = TimeZone.getDefault () .toZoneId ()

The resulting ZoneId object can then be integrated with LocalDate, LocalDateTime, or Instant objects to construct a ZonedDateTime instance that represents a point in time relative to the specified time zone:

LocalDate date = LocalDate.of (2019, Month.JANUARY, 1); ZonedDateTime zdt1 = date.atStartOfDay (romeZone); LocalDateTime dateTime = LocalDateTime.of (2019, Month.JANUARY, 18, 13, 45); ZonedDateTime zdt2 = dateTime.atZone (romeZone); Instant instant = Instant.now (); ZonedDateTime zdt3 = instant.atZone (romeZone)

With ZoneId, you can also convert LocalDateTime to Instant:

LocalDateTime dateTime = LocalDateTime.of (2019, Month.JANUARY, 18, 13, 45); Instant instantFromDateTime = dateTime.toInstant (romeZone)

You can also get the LocalDateTime object in reverse:

Instant instant = Instant.now (); LocalDateTime timeFromInstant = LocalDateTime.ofInstant (instant, romeZone)

Unlike Joda-Time, the date-time class library in Java8 provides four other calendar systems, each of which has a corresponding log class, namely ThaiBuddhistDate, MinguoDate, JapaneseDate, and HijrahDate. All of these classes, as well as LocalDate, implement the ChronoLocalDate interface to model the dates of the Gregorian calendar. With the LocalDate object, you can create instances of these classes. Similarly, with the static factory methods they provide, you can create an instance of any Temporal object.

LocalDate date = LocalDate.of (2019, Month.JANUARY, 1); JapaneseDate japaneseDate = JapaneseDate.from (date)

references

Joda-Time introduction to Joda Time project and java8 time api

Dynamic computing time period

Demand: if it is 13:00, the time period is 15:10-17:10, 17:10-19:10, 19:10-21 10; that is, the earliest departure time is the current time + parameter [2h20min], and the latest time period is the time period before 20:00 and ending time after 20:00). How many time periods are there in the solution?

Analysis:

The start time of the first time period: current time + parameter [2h20min], with 2 hours in the middle

By understanding this sentence: the latest time period is the period when the start time is before 20:00 and the end time is after 20:00, we can assume that the maximum time variable is max

Assuming that the current time is now, with a total of n time periods, the formula can be derived: now + (2h * n) + 10min

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report