在Java8中,引入了一个新的Date-Time API来弥补旧Date-Time API的以下缺点。
Not thread safe - java.util.Date不是线程安全的。
Poor design - 默认日期从1900年开始,因此不一致。
Difficult time zone handling - 开发人员必须编写大量代码来处理时区问题。
Java8在java.time包下引入了一个新的日期-时间API。下面是java.time包中引入的一些重要类。
Local(本地) - 简化了日期时间的处理,没有时区的问题。
Zoned(时区) - 通过制定的时区处理日期时间。
本地化API
LocalDate/localtime和LocalDateTime类简化了不需要时区的开发。
使用您选择的任何编辑器创建以下Java程序,例如,C:\> JAVA.
Java8Tester.java
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.Month;
public class Java8Tester {
public static void main(String args[]) {
Java8Tester java8tester=new Java8Tester();
java8tester.testLocalDateTime();
}
public void testLocalDateTime() {
//获取当前日期和时间
LocalDateTime currentTime=LocalDateTime.now();
System.out.println("Current DateTime: " + currentTime);
</span><span class="typ">LocalDate</span><span class="pln"> date1</span><span class="pun">=</span><span class="pln">currentTime</span><span class="pun">.</span><span class="pln">toLocalDate</span><span class="pun">();</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"date1: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> date1</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Month</span><span class="pln"> month</span><span class="pun">=</span><span class="pln">currentTime</span><span class="pun">.</span><span class="pln">getMonth</span><span class="pun">();</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> day</span><span class="pun">=</span><span class="pln">currentTime</span><span class="pun">.</span><span class="pln">getDayOfMonth</span><span class="pun">();</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> seconds</span><span class="pun">=</span><span class="pln">currentTime</span><span class="pun">.</span><span class="pln">getSecond</span><span class="pun">();</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Month: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> month </span><span class="pun">+</span><span class="str">"day: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> day </span><span class="pun">+</span><span class="str">"seconds: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> seconds</span><span class="pun">);</span><span class="pln">
</span><span class="typ">LocalDateTime</span><span class="pln"> date2</span><span class="pun">=</span><span class="pln">currentTime</span><span class="pun">.</span><span class="pln">withDayOfMonth</span><span class="pun">(</span><span class="lit">10</span><span class="pun">).</span><span class="pln">withYear</span><span class="pun">(</span><span class="lit">2012</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"date2: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> date2</span><span class="pun">);</span><span class="pln">
</span><span class="com">//2014年12月12日</span><span class="pln">
</span><span class="typ">LocalDate</span><span class="pln"> date3</span><span class="pun">=</span><span class="typ">LocalDate</span><span class="pun">.</span><span class="kwd">of</span><span class="pun">(</span><span class="lit">2014</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Month</span><span class="pun">.</span><span class="pln">DECEMBER</span><span class="pun">,</span><span class="pln"> </span><span class="lit">12</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"date3: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> date3</span><span class="pun">);</span><span class="pln">
</span><span class="com">//22小时15分钟</span><span class="pln">
</span><span class="typ">LocalTime</span><span class="pln"> date4</span><span class="pun">=</span><span class="typ">LocalTime</span><span class="pun">.</span><span class="kwd">of</span><span class="pun">(</span><span class="lit">22</span><span class="pun">,</span><span class="pln"> </span><span class="lit">15</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"date4: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> date4</span><span class="pun">);</span><span class="pln">
</span><span class="com">//解析一个字符串</span><span class="pln">
</span><span class="typ">LocalTime</span><span class="pln"> date5</span><span class="pun">=</span><span class="typ">LocalTime</span><span class="pun">.</span><span class="pln">parse</span><span class="pun">(</span><span class="str">"20:15:30"</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"date5: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> date5</span><span class="pun">);</span><span class="pln">
}
}
使用javac编译器编译类,如下所示-
C:\JAVA>javac Java8Tester.java
现在运行Java8Tester,如下所示-
C:\JAVA>java Java8Tester
它应该生成以下输出-
Current DateTime: 2014-12-09T11:00:45.457 date1: 2014-12-09 Month: DECEMBERday: 9seconds: 45 date2: 2012-12-10T11:00:45.457 date3: 2014-12-12 date4: 22:15 date5: 20:15:30
时区API
如果无涯教程需要考虑到时区,就可以使用时区的日期时间API:
Java8Tester.java
import java.time.ZonedDateTime;
import java.time.ZoneId;
public class Java8Tester {
public static void main(String args[]) {
Java8Tester java8tester=new Java8Tester();
java8tester.testZonedDateTime();
}
public void testZonedDateTime() {
//获取当前日期和时间
ZonedDateTime date1=ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Karachi]");
System.out.println("date1: " + date1);
</span><span class="typ">ZoneId</span><span class="pln"> id</span><span class="pun">=</span><span class="typ">ZoneId</span><span class="pun">.</span><span class="kwd">of</span><span class="pun">(</span><span class="str">"Europe/Paris"</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"ZoneId: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> id</span><span class="pun">);</span><span class="pln">
</span><span class="typ">ZoneId</span><span class="pln"> currentZone</span><span class="pun">=</span><span class="typ">ZoneId</span><span class="pun">.</span><span class="pln">systemDefault</span><span class="pun">();</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"CurrentZone: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> currentZone</span><span class="pun">);</span><span class="pln">
}
}
使用javac编译器编译类,如下所示-
C:\JAVA>javac Java8Tester.java
现在运行Java8Tester,如下所示-
C:\JAVA>java Java8Tester
它应该生成以下输出-
date1: 2007-12-03T10:15:30+05:00[Asia/Karachi] ZoneId: Europe/Paris CurrentZone: Etc/UTC
ChronoUnits枚举
在Java8中添加了java.time.Temporal.ChronoUnit枚举,以替换旧API中使用的整数值,以表示日、月等。让无涯教程看看它们的实际效果。
使用您选择的任何编辑器创建以下Java程序,例如, C:\> JAVA.
Java8Tester.java
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class Java8Tester {
public static void main(String args[]) {
Java8Tester java8tester=new Java8Tester();
java8tester.testChromoUnits();
}
public void testChromoUnits() {
//获取当前日期
LocalDate today=LocalDate.now();
System.out.println("Current date: " + today);
</span><span class="com">//往后增加1周的日期</span><span class="pln">
</span><span class="typ">LocalDate</span><span class="pln"> nextWeek</span><span class="pun">=</span><span class="pln">today</span><span class="pun">.</span><span class="pln">plus</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ChronoUnit</span><span class="pun">.</span><span class="pln">WEEKS</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Next week: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> nextWeek</span><span class="pun">);</span><span class="pln">
</span><span class="com">//往后增加1个月的日期</span><span class="pln">
</span><span class="typ">LocalDate</span><span class="pln"> nextMonth</span><span class="pun">=</span><span class="pln">today</span><span class="pun">.</span><span class="pln">plus</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ChronoUnit</span><span class="pun">.</span><span class="pln">MONTHS</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Next month: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> nextMonth</span><span class="pun">);</span><span class="pln">
</span><span class="com">//往后增加1年的日期</span><span class="pln">
</span><span class="typ">LocalDate</span><span class="pln"> nextYear</span><span class="pun">=</span><span class="pln">today</span><span class="pun">.</span><span class="pln">plus</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ChronoUnit</span><span class="pun">.</span><span class="pln">YEARS</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Next year: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> nextYear</span><span class="pun">);</span><span class="pln">
</span><span class="com">//增加10年的日期</span><span class="pln">
</span><span class="typ">LocalDate</span><span class="pln"> nextDecade</span><span class="pun">=</span><span class="pln">today</span><span class="pun">.</span><span class="pln">plus</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ChronoUnit</span><span class="pun">.</span><span class="pln">DECADES</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Date after ten year: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> nextDecade</span><span class="pun">);</span><span class="pln">
}
}
使用javac编译器编译类,如下所示-
C:\JAVA>javac Java8Tester.java
现在运行Java8Tester,如下所示-
C:\JAVA>java Java8Tester
它应该产生以下输出-
Current date: 2014-12-10 Next week: 2014-12-17 Next month: 2015-01-10 Next year: 2015-12-10 Date after ten year: 2024-12-10
Period和Duration
在Java8中,引入了两个专门的类来处理时间差异。
Period - 它处理基于日期的时间。
Duration - 它处理基于时间的时间。
使用您选择的任何编辑器创建以下Java程序,例如, C:\> JAVA.
Java8Tester.java
import java.time.temporal.ChronoUnit;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Duration;
import java.time.Period;
public class Java8Tester {
public static void main(String args[]) {
Java8Tester java8tester=new Java8Tester();
java8tester.testPeriod();
java8tester.testDuration();
}
public void testPeriod() {
//获取当前日期
LocalDate date1=LocalDate.now();
System.out.println("Current date: " + date1);
</span><span class="com">//往后增加1个月的日期</span><span class="pln">
</span><span class="typ">LocalDate</span><span class="pln"> date2</span><span class="pun">=</span><span class="pln">date1</span><span class="pun">.</span><span class="pln">plus</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ChronoUnit</span><span class="pun">.</span><span class="pln">MONTHS</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Next month: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> date2</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Period</span><span class="pln"> period</span><span class="pun">=</span><span class="typ">Period</span><span class="pun">.</span><span class="pln">between</span><span class="pun">(</span><span class="pln">date2</span><span class="pun">,</span><span class="pln"> date1</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Period: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> period</span><span class="pun">);</span><span class="pln">
}
public void testDuration() {
LocalTime time1=LocalTime.now();
Duration twoHours=Duration.ofHours(2);
</span><span class="typ">LocalTime</span><span class="pln"> time2</span><span class="pun">=</span><span class="pln">time1</span><span class="pun">.</span><span class="pln">plus</span><span class="pun">(</span><span class="pln">twoHours</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Duration</span><span class="pln"> duration</span><span class="pun">=</span><span class="typ">Duration</span><span class="pun">.</span><span class="pln">between</span><span class="pun">(</span><span class="pln">time1</span><span class="pun">,</span><span class="pln"> time2</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Duration: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> duration</span><span class="pun">);</span><span class="pln">
}
}
使用javac编译器编译类,如下所示-
C:\JAVA>javac Java8Tester.java
现在运行Java8Tester,如下所示-
C:\JAVA>java Java8Tester
它应该生成以下输出-
Current date: 2014-12-10 Next month: 2015-01-10 Period: P-1M Duration: PT2H
时间调节器
使用您选择的任何编辑器创建以下Java程序,例如, C:\> JAVA.
Java8Tester.java
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.time.DayOfWeek;
public class Java8Tester {
public static void main(String args[]) {
Java8Tester java8tester=new Java8Tester();
java8tester.testAdjusters();
}
public void testAdjusters() {
//获取当前日期
LocalDate date1=LocalDate.now();
System.out.println("Current date: " + date1);
</span><span class="com">//得到下一个星期二</span><span class="pln">
</span><span class="typ">LocalDate</span><span class="pln"> nextTuesday</span><span class="pun">=</span><span class="pln">date1</span><span class="pun">.</span><span class="kwd">with</span><span class="pun">(</span><span class="typ">TemporalAdjusters</span><span class="pun">.</span><span class="kwd">next</span><span class="pun">(</span><span class="typ">DayOfWeek</span><span class="pun">.</span><span class="pln">TUESDAY</span><span class="pun">));</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Next Tuesday on : "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> nextTuesday</span><span class="pun">);</span><span class="pln">
</span><span class="com">//获得下个月的第二个星期六</span><span class="pln">
</span><span class="typ">LocalDate</span><span class="pln"> firstInYear</span><span class="pun">=</span><span class="typ">LocalDate</span><span class="pun">.</span><span class="kwd">of</span><span class="pun">(</span><span class="pln">date1</span><span class="pun">.</span><span class="pln">getYear</span><span class="pun">(),</span><span class="pln">date1</span><span class="pun">.</span><span class="pln">getMonth</span><span class="pun">(),</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
</span><span class="typ">LocalDate</span><span class="pln"> secondSaturday</span><span class="pun">=</span><span class="pln">firstInYear</span><span class="pun">.</span><span class="kwd">with</span><span class="pun">(</span><span class="typ">TemporalAdjusters</span><span class="pun">.</span><span class="pln">nextOrSame</span><span class="pun">(</span><span class="pln">
</span><span class="typ">DayOfWeek</span><span class="pun">.</span><span class="pln">SATURDAY</span><span class="pun">)).</span><span class="kwd">with</span><span class="pun">(</span><span class="typ">TemporalAdjusters</span><span class="pun">.</span><span class="kwd">next</span><span class="pun">(</span><span class="typ">DayOfWeek</span><span class="pun">.</span><span class="pln">SATURDAY</span><span class="pun">));</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Second Saturday on : "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> secondSaturday</span><span class="pun">);</span><span class="pln">
}
}
使用javac编译器编译类,如下所示-
C:\JAVA>javac Java8Tester.java
现在运行Java8Tester,如下所示-
C:\JAVA>java Java8Tester
它应该产生以下输出-
Current date: 2014-12-10 Next Tuesday on : 2014-12-16 Second Saturday on : 2014-12-13
向后兼容性
TemporalAdjuster用于执行日期数学。 例如,获取“每月的第二个星期六”或“下一个星期二”。
Java8Tester.java
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.Date;
import java.time.Instant;
import java.time.ZoneId;
public class Java8Tester {
public static void main(String args[]) {
Java8Tester java8tester=new Java8Tester();
java8tester.testBackwardCompatability();
}
public void testBackwardCompatability() {
//获取当前日期
Date currentDate=new Date();
System.out.println("Current date: " + currentDate);
</span><span class="com">//根据毫秒获取当前日期的即时</span><span class="pln">
</span><span class="typ">Instant</span><span class="pln"> now</span><span class="pun">=</span><span class="pln">currentDate</span><span class="pun">.</span><span class="pln">toInstant</span><span class="pun">();</span><span class="pln">
</span><span class="typ">ZoneId</span><span class="pln"> currentZone</span><span class="pun">=</span><span class="typ">ZoneId</span><span class="pun">.</span><span class="pln">systemDefault</span><span class="pun">();</span><span class="pln">
</span><span class="typ">LocalDateTime</span><span class="pln"> localDateTime</span><span class="pun">=</span><span class="typ">LocalDateTime</span><span class="pun">.</span><span class="pln">ofInstant</span><span class="pun">(</span><span class="pln">now</span><span class="pun">,</span><span class="pln"> currentZone</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Local date: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> localDateTime</span><span class="pun">);</span><span class="pln">
</span><span class="typ">ZonedDateTime</span><span class="pln"> zonedDateTime</span><span class="pun">=</span><span class="typ">ZonedDateTime</span><span class="pun">.</span><span class="pln">ofInstant</span><span class="pun">(</span><span class="pln">now</span><span class="pun">,</span><span class="pln"> currentZone</span><span class="pun">);</span><span class="pln">
</span><span class="typ">System</span><span class="pun">.</span><span class="kwd">out</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">"Zoned date: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> zonedDateTime</span><span class="pun">);</span><span class="pln">
}
}
使用javac编译器编译类,如下所示-
C:\JAVA>javac Java8Tester.java
现在运行Java8Tester,如下所示-
C:\JAVA>java Java8Tester
它应该生成以下输出-
Current date: Wed Dec 10 05:44:06 UTC 2014 Local date: 2014-12-10T05:44:06.635 Zoned date: 2014-12-10T05:44:06.635Z[Etc/UTC]