This series of articles have been supplemented and improved, and has been revised and organized into a book, The Logic of Java Programming (written by Ma Junchang), published by Huazhang Branch of China Machine Press, which was on the market in January 2018 and received high praise from readers. Major online shops and bookstores are available for sale, welcome to buy: JINGdong self-run link

Joda-Time

In the last section, we introduced the date and Time classes in the JDK API. We mentioned some shortcomings of the JDK API and mentioned that there is a widely used date and Time library in practice, joda-time. In this section, we introduce joda-time. Joda-time is a tool for manipulating dates and times.

Joda-time’s website is www.joda.org/joda-time/. And the basic concept and the way it works is similar to what we saw in the last video, for example, you have time and calendar, you have time and Locale, and the main job is to convert between milliseconds and calendar information like year, month and day.

There is also a rough correspondence between joda-time’s main classes and Java API classes:

| Joda – Time | | Java API specification | | — — — — — — — — — — — — – | — — — — — — — — — — — — – | | Instant | Date Time | | | DateTime | Calendar | Calendar | | DateTimeZone | TimeZone | time zone | | DateTimeFormatter | DateFormat format | |

It should be noted that this is only a very rough correspondence and is not rigorous, and there are many other classes of joda-time as well.

While the basic concepts are similar, the API design is quite different. Joda-time’s API is much easier to understand and use, and the code is much cleaner, as we’ll illustrate with examples below.

In addition, the main classes in Joda-time are designed to be immutable, as we have described before. The wrapper class /String is immutable. Immutable classes have the great advantage of being simple and thread-safe. Everything that looks like a modification is done by creating new objects.

This article is not intended to cover every class of Joda-time. Instead, we will focus on examples to illustrate its basic usage, its convenience and power, and the design philosophy of its API.

Create an object

Create a DateTime object representing the current date and time:

DateTime dt = new DateTime();
Copy the code

Create a DateTime object, given year, month, day, hour, minute, second and so on:

/ / the 2016-08-18 only
DateTime dt = new DateTime(2016.8.18.15.20);

/ / the 2016-08-18 15:20:47
DateTime dt2 = new DateTime(2016.8.18.15.20.47);

/ / the 15:20:47 2016-08-18. 345
DateTime dt3 = new DateTime(2016.8.18.15.20.47.345);
Copy the code

Get calendar information

Unlike Calendar, DateTime provides a separate method for each Calendar field, and the range of values is common sense and easy to understand and use.

/ / the 15:20:47 2016-08-18. 345
DateTime dt = new DateTime(2016.8.18.15.20.47.345);
System.out.println("year: "+dt.getYear());
System.out.println("month: "+dt.getMonthOfYear());
System.out.println("day: "+dt.getDayOfMonth());
System.out.println("hour: "+dt.getHourOfDay());
System.out.println("minute: "+dt.getMinuteOfHour());
System.out.println("second: "+dt.getSecondOfMinute());
System.out.println("millisecond: " +dt.getMillisOfSecond());
System.out.println("day_of_week: " +dt.getDayOfWeek());
Copy the code

The output is:

year: 2016
month: 8
day: 18
hour: 15
minute: 20
second: 47
millisecond: 345
day_of_week: 4
Copy the code

The output of each field is common sense and consistent, starting at 1, for example, dayOfWeek, which is 4 on Thursday, which is easy to understand.

formatting

In Java APIS, formatting must use a DateFormat object. In Joda-time, DateTime itself has a toString method that accepts a pattern argument.

/ / the 14:20:45 2016-08-18. 345
DateTime dt = new DateTime(2016.8.18.14.20.45.345);
System.out.println(dt.toString("yyyy-MM-dd HH:mm:ss"));
Copy the code

The output is:

2016-08-18 14:20:45
Copy the code

Joda-time also has a class similar to DateFormat.

DateTime dt = new DateTime(2016.8.18.14.20);
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
System.out.println(formatter.print(dt));
Copy the code

The output is:

The 2016-08-18 mostCopy the code

There are two classes, DateTimeFormat and DateTimeFormatter. DateTimeFormatter is the concrete formatting class that provides a print method to convert a DateTime to a string. DateTimeFormat is a factory class that produces concrete formatting classes. It has other factory methods besides the forPattern method that are not covered in this article.

A basic thinking of program design is the separation of concerns, the program is generally more complex, involving all aspects, the solution is to decompose, the complex things as far as possible into different aspects, or concerns, the coupling degree between concerns should be as low as possible.

Specifically, for Java, each class should focus on just one point. The factory class DateTimeFormat is used to generate the DateTimeFormatter. The factory class DateTimeFormat is used to generate the DateTimeFormatter. There are other factory classes in Joda-time, such as ISODateTimeFormat, and the factory class is a common design pattern.

In addition to converting a DateTime to a string, the DateTimeFormatter can also convert a string to a DateTime as follows:

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
DateTime dt = formatter.parseDateTime(He "2016-08-18");
Copy the code

Unlike the formatting classes described in the previous section, the DateTimeFormatter of Joda-time is thread-safe and can be safely shared by multiple threads.

Set and modify the time

As mentioned in the previous section about Calendar, there are two ways to change the date and time: one is to set absolute values directly, and the other is to add or subtract relative values from existing values. DateTime also supports these two ways.

However, it is important to note that DateTime is an immutable class, and modification is done by creating and returning a new object. The original object itself does not change.

Let’s look at some examples.

The time will be adjusted to 3:20 p.m

DateTime dt = new DateTime();
dt = dt.withHourOfDay(15).withMinuteOfHour(20);
Copy the code

DateTime has many withXXX methods to set the absolute time. The convenience of DateTime is that the return value of a method is a modified DateTime object, which can be followed by the next method call. This makes the code very clean and easy to read, a popular design style known as the Fluent Interface. In contrast, To use Calendar, you have to write multiple lines of code, which is quite bloated, as we’ll see more examples below.

Also, note that you need to assign the final return value to dt, otherwise the value of DT will not change.

In three hours and five minutes

DateTime dt = new DateTime().plusHours(3).plusMinutes(5);
Copy the code

DateTime has a number of plusXXX and minusXXX methods for relatively increasing and decreasing time.

0 points today

DateTime dt = new DateTime().withMillisOfDay(0);
System.out.println(dt.toString("yyyy-MM-dd HH:mm:ss.SSS"));
Copy the code

The current time is 2016-08-18, so the output is

2016-08-18 00:00:00. 000Copy the code

Withzippered day sets the millisiew of day and changes the time, minutes and seconds.

Next Tuesday at ten sharp

DateTime dt = new DateTime().plusWeeks(1).withDayOfWeek(2)
        .withMillisOfDay(0).withHourOfDay(10);
Copy the code

Tomorrow at the last minute

DateTime dt = new DateTime().plusDays(1).millisOfDay().withMaximumValue();
System.out.println(dt.toString("yyyy-MM-dd HH:mm:ss.SSS"));
Copy the code

The current time is 2016-08-18, so the output is

The 2016-08-19 23:59:59. 999Copy the code

So just to be clear, plusDays(1) is easy to understand, so set it to the next day. [^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105 ^ # 105]? WithMaximumValue sets the value of this property to the maximum value.

So, isn’t the code pretty neat? DateTime has a lot of similar attributes besides zipofday. Let’s look at some more examples.

Last minute on the last day of the month

DateTime dt = new DateTime().dayOfMonth().withMaximumValue().millisOfDay().withMaximumValue();
Copy the code

5:00 p.m. on the first Monday of next month

DateTime dt = new DateTime().plusMonths(1).dayOfMonth().withMinimumValue()
        .plusDays(6).withDayOfWeek(1).withMillisOfDay(0).withHourOfDay(17);
Copy the code

Let’s explain a little bit:

new DateTime().plusMonths(1).dayOfMonth().withMinimumValue()
Copy the code

Set it for the first day of the next month. .plusDays(6).withDAYofWeek (1) Set the time to the first Monday.

Calculation of time periods

There are no classes in the JDK API for calculating Time periods, and Joda-time contains a wealth of methods for representing Time periods and calculating Time periods. Let’s look at some examples.

Calculate the difference between the two times

Joda-time has a class, Period, which stands for a Period of Time by calendar information.

DateTime start = new DateTime(2016.8.18.10.58);
DateTime end = new DateTime(2016.9.19.12.3);
Period period = new Period(start,end);        
System.out.println(period.getMonths()+"Month"+period.getDays()+"Day"
        +period.getHours()+"Hour"+period.getMinutes()+"Points");
Copy the code

The output is:

1 month 1 day 1 hour 5 minutesCopy the code

A Period automatically calculates the number of months, days, hours, etc.

What if we just care about how many days we have, or how many weeks we have? Joda-time has special classes, such as Years for Years, Days for Days and Minutes for Minutes.

Calculate age according to birthday

Age only cares about Years, you can use Years, see code:

DateTime born = new DateTime(1990.11.20.12.30);
int age = Years.yearsBetween(born, DateTime.now()).getYears();
Copy the code

Count the minutes you are late

Suppose 9 am is the time to start work, after 9 am is considered late, late to count the number of minutes, how to calculate? Look at the code:

int lateMinutes = Minutes.minutesBetween(
        DateTime.now().withMillisOfDay(0).withHourOfDay(9),
        DateTime.now()).getMinutes(); 
Copy the code

Separate date and time classes

We’ve been using DateTime to represent the full date and Time, but in the age case, you only care about the date, and in the late case, you only care about the Time. Joda-time has separate date classes LocalDate and Time classes LocalTime.

Use LocalDate to calculate the age

LocalDate born = new LocalDate(1990.11.20);
int age = Years.yearsBetween(born, LocalDate.now()).getYears();
Copy the code

Use LocalTime to calculate the lateness time

int lateMinutes = Minutes.minutesBetween(
        new LocalTime(9.0),
        LocalTime.now()).getMinutes();
Copy the code

LocalDate and LocalTime can be converted to DateTime, for example:

DateTime dt = new DateTime(1990.11.20.12.30);
LocalDate date = dt.toLocalDate();
LocalTime time = dt.toLocalTime();
DateTime newDt = DateTime.now().withDate(date).withTime(time);
Copy the code

Interoperability with JDK apis

Classes in Joda-time can be easily converted to and from JDK classes.

JDK -> Joda

Date and Calendar can be easily converted to DateTime objects:

DateTime dt = new DateTime(new Date());
DateTime dt2 = new DateTime(Calendar.getInstance());
Copy the code

You can also easily convert to LocalDate and LocalTime objects:

LocalDate.fromDateFields(new Date());
LocalDate.fromCalendarFields(Calendar.getInstance());
LocalTime.fromDateFields(new Date());
LocalTime.fromCalendarFields(Calendar.getInstance());
Copy the code

Joda -> JDK

DateTime objects can also be easily converted to JDK objects:

DateTime dt = new DateTime();
Date date = dt.toDate();
Calendar calendar = dt.toCalendar(Locale.CHINA);
Copy the code

LocalDate can also be converted to a Date object:

LocalDate localDate = new LocalDate(2016.8.18);
Date date = localDate.toDate();
Copy the code

summary

This section introduces Joda-time, a convenient and powerful date and Time library that is not fully covered in this article, but rather demonstrates its basic usage through some examples.

We also introduced some of the design ideas that make Joda-time easy to use, such as separation of concerns, providing separate, functional classes and methods for ease of operation, designing the API as a smooth interface, designing immutable classes, and using factory classes.

In the next video, we’ll talk about an interesting topic, which is randomness.


To be continued, check the latest articles, please pay attention to the wechat public account “Lao Ma said programming” (scan the qr code below), simple and simple, Lao Ma and you explore the nature of Java programming and computer technology. All rights reserved.