Detailed explanation of the use of time in java8 (with examples)
This article brings you a detailed explanation of the use of time in Java8 (with examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Why is a new time API needed?
Before the date/time API before Java 8, there were many problems with existing date and time-related classes, the main ones being:
The definition of Java's date/time classes is not consistent. There are date classes in the java.util and java.sql packages. In addition, classes used for formatting and parsing are defined in the java.text package
java.util.Date contains both date and time, while java.sql.Date only contains date, and it is not reasonable to include it in the java.sql package. Plus both classes have the same name, which in itself is a very bad design.
There are no clearly defined classes for time, timestamps, formatting and parsing. For formatting and parsing needs we have java.text.DateFormat abstract class but usually SimpleDateFormat class is used for such needs.
All date classes are mutable, therefore they are not thread-safe, which is one of the biggest problems with Java date classes.
The date class does not provide internationalization and has no time zone support, so Java introduced the java.util.Calendar and java.util.TimeZone classes, but they also have all the above problems.
There are some other problems with the methods defined in the existing date and calendar classes, but the above issues make it clear that Java needs a robust date/time class. This is why Joda Time plays an important role as a high-quality replacement for Java date/time needs.
Note when using dates before java8
1 2 3 |
|
java8 concepts
Instant time (Instant), duration (duration) , date (date), time (time), time zone (time-zone) and time period (Period). Java 8 still uses the ISO calendar system, and unlike its predecessors, the classes in the java.time package are immutable and thread-safe. The new time and date API is located in the java.time package. Here are some key classes in it:
Instant - it represents a timestamp (because it represents a certain time point, that is, the offset relative to January 1, 1970; but unlike the java.util.Date class, it is accurate to the nanosecond level.
Duration: Duration, time difference
LocalDate - a date that does not contain a specific time, such as 2019-01-14. It can be used to store birthdays, anniversaries, entry dates, etc.
LocalTime - It represents time without date
LocalDateTime - It contains date and time, but there is still no offset information Or time zone.
Period: time period
ZoneOffset: time zone offset, for example: 8:00
ZonedDateTime - This is a complete datetime including time zone, offset from UTC/Greenwich Mean Time.
Clock: Clock , such as getting the current time in New York, USA
java8 time API features
Invariance: In the new date/time API, all classes They are all immutable, which is good for multi-threading.
Separation of concerns: Drawing on some advantages of the Joda library, the new API combines human-readable date and time with machine Time (unix timestamp) is clearly separated, which defines different classes for date (Date), time (Time), date time (DateTime), timestamp (unix timestamp) and time zone.
Clarity: In all classes, methods are clearly defined to accomplish the same behavior. For example, to get the current instance, we can use the now() method. format() and parse() are defined in all classes ) method, instead of having an independent class as before. In order to better handle the problem, all classes use the factory pattern and the strategy pattern. Once you use the method of one of the classes, it will work together with other classes. Not difficult.
Practical operations: All new date/time API classes implement a series of methods to complete common tasks, such as: addition, subtraction, formatting, parsing , extract individual parts from a date/time, etc.
Extensibility: The new date/time API is designed to work on the ISO-8601 calendar system, but we can also Apply it to non-IOS calendars.
java8 Date/Time API Package
java.time Package: This is the new Java The basic package of the date/time API. All major basic classes are part of this package, such as: LocalDate, LocalTime, LocalDateTime, Instant, Period, Duration, etc. All of these classes are immutable and thread-safe, and in most cases, these classes handle common requirements effectively.
java.time.chrono package: This package defines some generalized APIs for non-ISO calendar systems. We can extend the AbstractChronology class to create our own calendar system.
java.time.format包:这个包包含能够格式化和解析日期时间对象的类,在绝大多数情况下,我们不应该直接使用它们,因为java.time包中相应的类已经提供了格式化和解析的方法。
java.time.temporal包:这个包包含一些时态对象,我们可以用其找出关于日期/时间对象的某个特定日期或时间,比如说,可以找到某月的第一天或最后一天。你可以非常容易地认出这些方法,因为它们都具有“withXXX”的格式。
java.time.zone包:这个包包含支持不同时区以及相关规则的类。
java8 API介绍和使用
LocalDate
LocalDate 依然是一个不可变类,它关注时间中年月日部分
1 2 3 4 5 6 |
|
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
在java8中,可以使用MonthDay,该类不包含年份信息,当然还有一个类是YearMonth
1 2 3 4 5 6 |
|
TemporalAdjuster
但是有些时候我们要面临更复杂的时间操作,比如将时间调到下一个工作日,或者是下个月的最后一天,这时候我们可以使用with()方法的另一个重载方法,它接收一个TemporalAdjuster参数,可以使我们更加灵活的调整日期:
1 2 |
|
如果本身API不满足你的需求,你还可以创建自定义的TemporalAdjuster接口的实现
LocalTime
类似于 LocalDate,LocalTime 专注于时间的处理,它提供小时,分钟,秒,毫微秒的各种处理
1 2 3 4 5 6 7 |
|
示例
1 2 3 4 5 6 7 8 |
|
LocalDateTime
LocalDateTime类是LocalDate和LocalTime的结合体,可以通过of()方法直接创建,也可以调用LocalDate的atTime()方法或LocalTime的atDate()方法将LocalDate或LocalTime合并成一个LocalDateTime
1 2 3 4 5 |
|
LocalDateTime也提供用于向LocalDate和LocalTime的转化:
1 2 |
|
Instant
Instant用于表示一个时间戳,它与我们常使用的System.currentTimeMillis()有些类似,不过Instant可以精确到纳秒(Nano-Second),System.currentTimeMillis()方法只精确到毫秒(Milli-Second)。如果查看Instant源码,发现它的内部使用了两个常量,seconds表示从1970-01-01 00:00:00开始到现在的秒数,nanos表示纳秒部分(nanos的值不会超过999,999,999)。Instant除了使用now()方法创建外,还可以通过ofEpochSecond方法创建:
1 |
|
时间差
关于时间差的计算,主要涉及到两个类,年月日的日期间差值的计算使用 Period 类足以,而时分秒毫秒的时间的差值计算则需要使用Duration类。
Duration:处理两个时间之间的差值
1
2
3
4
5
6
7
8
9
10
LocalDateTime from = LocalDateTime.of(2019, Month.JANUARY, 5, 10, 7, 0);
// 2019-01-05 10:07:00
LocalDateTime to = LocalDateTime.of(2019, Month.FEBRUARY, 5, 10, 7, 0);
// 2019-02-05 10:07:00
Duration duration = Duration.between(from, to);
// 表示从 2019-01-05 10:07:00 到 2019-02-05 10:07:00 这段时间
long days = duration.toDays();
// 这段时间的总天数
long hours = duration.toHours();
// 这段时间的小时数
long minutes = duration.toMinutes();
// 这段时间的分钟数
long seconds = duration.getSeconds();
// 这段时间的秒数
long milliSeconds = duration.toMillis();
// 这段时间的毫秒数
long nanoSeconds = duration.toNanos();
// 这段时间的纳秒数
Copy after loginDuration对象还可以通过of()方法创建,该方法接受一个时间段长度,和一个时间单位作为参数:
1
2
Duration duration1 = Duration.of(5, ChronoUnit.DAYS);
// 5天
Duration duration2 = Duration.of(1000, ChronoUnit.MILLIS);
// 1000毫秒
Copy after loginDuration的内部实现与Instant类似,也是包含两部分:seconds表示秒,nanos表示纳秒。两者的区别是Instant用于表示一个时间戳(或者说是一个时间点),而Duration表示一个时间段,所以Duration类中不包含now()静态方法。可以通过Duration.between()方法创建
Period:处理两个日期之间的差值
Period在概念上和Duration类似,区别在于Period是以年月日来衡量一个时间段,比如2年3个月6天
1
Period period = Period.of(2, 3, 6);
Copy after loginPeriod对象也可以通过between()方法创建,值得注意的是,由于Period是以年月日衡量时间段,所以between()方法只能接收LocalDate类型的参数:
1
2
3
Period period = Period.between(
LocalDate.of(2019, 1, 5),
LocalDate.of(2019, 2, 5));
Copy after login示例
1 2 3 4 5 6 7 8 9 10 11 |
|
ZonedDateTime
无论是我们的 LocalDate,或是 LocalTime,甚至是 LocalDateTime,它们基本是时区无关的,内部并没有存储时区属性,而基本用的系统默认时区。往往有些场景之下,缺乏一定的灵活性。
ZonedDateTime 可以被理解为 LocalDateTime 的外层封装,它的内部存储了一个 LocalDateTime 的实例,专门用于普通的日期时间处理。此外,它还定义了 ZoneId 和 ZoneOffset 来描述时区的概念。
ZonedDateTime 和 LocalDateTime 的一个很大的不同点在于,后者内部并没有存储时区,所以对于系统的依赖性很强,往往换一个时区可能就会导致程序中的日期时间不一致。
而后者则可以通过传入时区的名称,使用 ZoneId 进行匹配存储,也可以通过传入与零时区的偏移量,使用 ZoneOffset 存储时区信息。
1 2 3 4 5 6 7 |
|
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
第一个输出应使用了当前系统日期和时间以及默认的时区。
第二个小例子,LocalDateTime 实例保存了时区无关的当前日期时间信息,也就是这里的年月日时分秒,接着构建一个 ZonedDateTime 实例并传入一个美国时区(西七区)。你会发现输出的日期时间为西七区的 16 点 27 分。
像这种关联了时区的日期时间就很能够解决那种,换时区导致程序中时间错乱的问题。因为我关联了时区,无论你程序换到什么地方运行了,日期+时区 本就已经唯一确定了某个时刻,就相当于我在存储某个时刻的时候,说明了这是某某时区的某某时间,即便你换了一个地区,也不至于把这个时间按自己当前的时区进行解析并直接使用。
第三个小例子,构建 ZonedDateTime实例的时候,给定一个时刻和一个时区,而这个时刻值就是相对于给定时区的标准时间所经过的毫秒数。
有关 ZonedDateTime 的其他日期时间的处理方法和 LocalDateTime 是一样的,因为 ZonedDateTime 是直接封装了一个 LocalDateTime 实例对象,所以所有相关日期时间的操作都会间接的调用 LocalDateTime 实例的方法,我们不再赘述。
格式化日期时间
Java 8 的新式日期时间 API 中,DateTimeFormatter 作为格式化日期时间的主要类,它与之前的 DateFormat 类最大的不同就在于它是线程安全的,如果需要的话,可以赋值给一个静态变量。
DateTimeFormatter类提供了许多预定义的格式器,你也可以自定义自己想要的格式。当然根据约定,它还有一个parse()方法是用于将字符串转换成日期的,如果转换期间出现任何错误,它会抛出DateTimeParseException异常。类似的,DateFormatter类也有一个用于格式化日期的format()方法,它出错的话则会抛出DateTimeException异常
再说一句,“MMM d yyyy”与“MMm dd yyyy”这两个日期格式也略有不同,前者能识别出"Jan 2 2018"与"Jan 14 2018"这两个串,而后者如果传进来的是"Jan 2 2018"则会报错,因为它期望月份处传进来的是两个字符。为了解决这个问题,在天为个位数的情况下,你得在前面补0,比如"Jan 2 2018"应该改为"Jan 02 2018"。
1 2 3 4 5 6 7 8 9 10 11 |
|
java8 时间与老版本时间转换
因为java8之前Date是包含日期和时间的,而LocalDate只包含日期,LocalTime只包含时间,所以与Date在互转中,势必会丢失日期或者时间,或者会使用起始时间。如果转LocalDateTime,那么就不存在信息误差。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
The above is the detailed content of Detailed explanation of the use of time in java8 (with examples). For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Java8 calculates the date one year ago or one year later using the minus() method to calculate the date one year ago packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[]args ){LocalDatetoday=LocalDate.now();LocalDatepreviousYear=today.minus(1,ChronoUni

How to calculate the date one week later in Java8 This example will calculate the date one week later. The LocalDate date does not contain time information. Its plus() method is used to add days, weeks, and months. The ChronoUnit class declares these time units. Since LocalDate is also an immutable type, you must use variables to assign values after returning. packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

Java8's Clock class Java8 adds a Clock class for obtaining the current timestamp, or date and time information in the current time zone. Where System.currentTimeInMillis() and TimeZone.getDefault() were used before, they can be replaced by Clock. packagecom.shxt.demo02;importjava.time.Clock;publicclassDemo10{publicstaticvoidmain(String[]args){//Returnsthecurrenttimebase

Handling time zones in Java 8 Java 8 not only separates date and time, but also separates time zones. There are now a series of separate classes such as ZoneId to handle specific time zones and ZoneDateTime to represent time in a certain time zone. This was done by the GregorianCalendar class before Java8. The following example shows how to convert the time in this time zone to the time in another time zone. packagecom.shxt.demo02;importjava.time.LocalDateTime;importjava.time.ZoneId;importjava.time.ZonedDateT

Get the current timestamp in Java8. The Instant class has a static factory method now() that returns the current timestamp, as shown below: packagecom.shxt.demo02;importjava.time.Instant;publicclassDemo16{publicstaticvoidmain(String[]args) {Instanttimestamp=Instant.now();System.out.println("Whatisvalueofthisinstant"+timestamp.t

How to use predefined formatting tools to parse or format dates in Java8 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.format.DateTimeFormatter;publicclassDemo17{publicstaticvoidmain(String[]args){StringdayAfterTommorrow="20180205 ";LocalDateformatted=LocalDate.parse

Get today's date in Java8 LocalDate in Java8 is used to represent today's date. Unlike java.util.Date, it only has dates and does not include time. Use this class when you only need to represent dates. packagecom.shxt.demo02;importjava.time.LocalDate;publicclassDemo01{publicstaticvoidmain(String[]args){LocalDatetoday=LocalDate.now();System.out.println("Today’s date:&q

Determine whether two dates are equal in Java8 packagecom.shxt.demo02;importjava.time.LocalDate;publicclassDemo04{publicstaticvoidmain(String[]args){LocalDatedate1=LocalDate.now();LocalDatedate2=LocalDate.of(2018,2,5) ;if(date1.equals(date2)){System.out.println("Times are equal");}e
