亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

全面解析Java日期時(shí)間API

robin / 1451人閱讀

摘要:類(lèi)是一個(gè)抽象類(lèi),它為特定瞬間與一組諸如等日歷字段之間的轉(zhuǎn)換提供了一些方法,并為操作日歷字段例如獲得下星期的日期提供了一些方法。是不變的日期時(shí)間對(duì)象代表一個(gè)日期時(shí)間,往往被視為年月日時(shí)分秒。獲得實(shí)例的日期和時(shí)間。

時(shí)區(qū)

GMT(Greenwich Mean Time):格林尼治時(shí)間,格林尼治標(biāo)準(zhǔn)時(shí)間的正午是指當(dāng)太陽(yáng)橫穿格林尼治子午線時(shí)(也就是在格林尼治上空最高點(diǎn)時(shí))的時(shí)間。

UTC(Universal Time Coordinated):統(tǒng)一協(xié)調(diào)時(shí)間,其以原子時(shí)秒長(zhǎng)為基礎(chǔ),在時(shí)刻上盡量接近于格林尼治標(biāo)準(zhǔn)時(shí)間,標(biāo)準(zhǔn) UTC 時(shí)間格式 yyyy-MM-dd"T"HH:mm:ss.SSSXXX。

格林尼治時(shí)間已經(jīng)不再被作為標(biāo)準(zhǔn)時(shí)間使用,UTC 是最主要的世界時(shí)間標(biāo)準(zhǔn)。

Java提供了獲取當(dāng)前時(shí)間的方法

System.currentTimeMillis(),返回當(dāng)前時(shí)間,以毫秒為單位,表示的就是當(dāng)前時(shí)刻至 1970-01-01 00:00:00.000 的毫秒差值。返回的long值可以用來(lái)初始化java.util.Date, java.sql.Date, java.sql.Timestamp和java.util.GregorianCalendar對(duì)象。

System.nanoTime(),返回一個(gè)時(shí)間值(系統(tǒng)計(jì)時(shí)器的當(dāng)前值),精確到納秒。它是由 JVM 提供的一個(gè)時(shí)間,主要用來(lái)精確衡量?jī)蓚€(gè)時(shí)間段之間的時(shí)間

例如,要測(cè)量一些代碼需要執(zhí)行多長(zhǎng)時(shí)間,實(shí)現(xiàn)如下,

long startTime = System.nanoTime();
//...the code being measured
long estimatedTime = System.nanoTime() - startTime;
時(shí)間粒度
事實(shí)上System.currentTimeMillis()方法的時(shí)間粒度是大于1毫秒的。如果你反復(fù)執(zhí)行這個(gè)方法,你會(huì)發(fā)現(xiàn)短時(shí)間內(nèi)得到的結(jié)果是相同的,隨后又突然在某一次結(jié)果增加了幾十毫秒(也可能更多)。這是很正常的,畢竟這個(gè)方法肯定不是世界上最精密的計(jì)時(shí)器。
舊的時(shí)間API

舊的時(shí)間API存在諸多問(wèn)題,例如

Java的日期/時(shí)間類(lèi)的定義并不一致,在java.util和java.sql的包中都有日期類(lèi),此外用于格式化和解析的類(lèi)在java.text包中定義。

java.util.Date同時(shí)包含日期和時(shí)間,而java.sql.Date僅包含日期,將其納入java.sql包并不合理。另外這兩個(gè)類(lèi)都有相同的名字,這本身就是一個(gè)非常糟糕的設(shè)計(jì)。

對(duì)于時(shí)間、時(shí)間戳、格式化以及解析,并沒(méi)有一些明確定義的類(lèi)。對(duì)于格式化和解析的需求,我們有java.text.DateFormat抽象類(lèi),但通常情況下,SimpleDateFormat類(lèi)被用于此類(lèi)需求。

所有的日期類(lèi)都是可變的,因此他們都不是線程安全的,這是Java日期類(lèi)最大的問(wèn)題之一。

日期類(lèi)并不提供國(guó)際化,沒(méi)有時(shí)區(qū)支持,因此Java引入了java.util.Calendar和java.util.TimeZone類(lèi),但他們同樣存在上述所有的問(wèn)題。

java.util.Date類(lèi)

java.util.Date類(lèi)用于封裝日期及時(shí)間信息,一般僅用它顯示某個(gè)日期,不對(duì)他作任何操作處理,作處理推薦用Calendar類(lèi),計(jì)算方便。以下已過(guò)時(shí)的方法沒(méi)有列出,可自行查看jdk文檔

構(gòu)造方法

Date() :分配 Date對(duì)象并初始化此對(duì)象,以表示分配它的時(shí)間(精確到毫秒)。

Date(long date):分配 Date對(duì)象并初始化此對(duì)象,以表示自從標(biāo)準(zhǔn)基準(zhǔn)時(shí)間(稱為“歷元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以來(lái)的指定毫秒數(shù)。

//1、使用Date類(lèi)獲取當(dāng)前系統(tǒng)時(shí)間
Date date = new Date();
System.out.println(date);
//由于Date類(lèi)覆蓋了toString()方法,所以可以直接輸出Date類(lèi)型的對(duì)象
//輸出結(jié)果為Fri May 31 10:51:18 GMT+08:00 2019

/*給Date設(shè)置年份需要減去 1900
*輸出結(jié)果Tue Jul 01 00:00:00 GMT+08:00 3919
*原來(lái)這里存在一個(gè)起始年份 1900,實(shí)際年份是要在你的年份參數(shù)上加上個(gè)起始年份。
*/
Date date1 = new Date(2019,5,31);
System.out.println(date1);

//2.分配 Date 對(duì)象并初始化此對(duì)象,以表示自從標(biāo)準(zhǔn)基準(zhǔn)時(shí)間(稱為“歷元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以來(lái)的指定毫秒數(shù)。
Date date2 = new Date(System.currentTimeMillis());//參數(shù)為19701月1日以來(lái)的毫秒數(shù)
Date date3 = new Date(1559284293556l); //long類(lèi)型要加l
System.out.println(date2);
System.out.println(date3);
//其他Date方法摘要可查看api
Calendar類(lèi)與GregorianCalendar

java.util.Calendar類(lèi)用于封裝日歷信息,其主作用在于其方法可以對(duì)時(shí)間分量進(jìn)行運(yùn)算。Calendar類(lèi)是一個(gè)抽象類(lèi),它為特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日歷字段之間的轉(zhuǎn)換提供了一些方法,并為操作日歷字段(例如獲得下星期的日期)提供了一些方法。

由于Calendar類(lèi)是抽象類(lèi),且Calendar類(lèi)的構(gòu)造方法是protected的,所以無(wú)法使用Calendar類(lèi)的構(gòu)造方法來(lái)創(chuàng)建對(duì)象,API中提供了getInstance方法用來(lái)創(chuàng)建對(duì)象。

Java只提供java.util.GregorianCalendar這一種java.util.Calendar的實(shí)現(xiàn)類(lèi),可以直接新建出來(lái)使用:

Calendar calendar = new GregorianCalendar();//新建出來(lái)的calendar默認(rèn)時(shí)間為當(dāng)前時(shí)間,或者說(shuō)創(chuàng)建出這個(gè)對(duì)象的時(shí)間。

通過(guò)Calendar的靜態(tài)方法獲取一個(gè)實(shí)例該方法會(huì)根據(jù)當(dāng)前系統(tǒng)所在地區(qū)來(lái)自行決定時(shí)區(qū),幫我們創(chuàng)建Calendar實(shí)例,這里要注意,實(shí)際上根據(jù)不同的地區(qū),Calendar有若干個(gè)子類(lèi)實(shí)現(xiàn)。而Calendar本身是抽象類(lèi),不能被實(shí)例化!我們不需要關(guān)心創(chuàng)建的具體實(shí)例為哪個(gè)子類(lèi),我們只需要根據(jù)Calendar規(guī)定的方法來(lái)使用就可以了。

日歷類(lèi)所解決的根本問(wèn)題是簡(jiǎn)化日期的計(jì)算,要想表示某個(gè)日期還應(yīng)該使用Date類(lèi)描述。Calendar是可以將其描述的時(shí)間轉(zhuǎn)化為Date的,我們只需要調(diào)用其getTime()方法就可以獲取描述的日期的Date對(duì)象了。

通過(guò)日歷類(lèi)計(jì)算時(shí)間:為日歷類(lèi)設(shè)置時(shí)間,日歷類(lèi)設(shè)置時(shí)間使用通用方法set。set(int field,int value),field為時(shí)間分量,Calendar提供了相應(yīng)的常量值,value為對(duì)應(yīng)的值。

只有月份從0開(kāi)始:0為1月,以此類(lèi)推,11為12月,其他時(shí)間是正常的從1開(kāi)始。也可以使用Calendar的常量 calendar.NOVEMBER……等。

Calendar.DAY_OF_MONTH  月里邊的天---號(hào);
Calendar.DAY_OF_WEEK    星期里的天---星期幾
Calendar.DAY_OF_YEAR     年里的天
Calendar calendar=Calendar.getInstance();//構(gòu)造出來(lái)表示當(dāng)前時(shí)間的日歷類(lèi)
Date now=calendar.getTime();//獲取日歷所描述的日期
calendar.set(Calendar.YEAR, 2019);//設(shè)置日歷表示2019年 calendar.set(Calendar.DAY_OF_MONTH,15);//設(shè)置日歷表示15號(hào)
calendar.add(Calendar.DAY_OF_YEAR, 22);//想得到22天以后是哪天
calendar.add(Calendar.DAY_OF_YEAR, -5);//5天以前是哪天
calendar.add(Calendar.MONTH, 1);得到1個(gè)月后是哪天
System.out.println(calendar.getTime());

獲取當(dāng)前日歷表示的日期中的某個(gè)時(shí)間單位可以使用get方法。

int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH)
int day = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(year+"年"+(month+1)+"月"+day+"日");//month要處理
SimpleDateFormat類(lèi)

常用構(gòu)造方法

SimpleDateFormat(String pattern),pattern -為描述日期和時(shí)間格式的模式

用給定的模式和默認(rèn)語(yǔ)言環(huán)境的日期格式符號(hào)構(gòu)造 SimpleDateFormat。 注:此構(gòu)造方法可能不支持所有語(yǔ)言環(huán)境。要覆蓋所有語(yǔ)言環(huán)境,請(qǐng)使用 DateFormat 類(lèi)中的工廠方法。

常用方法

public final String format(Date date)將一個(gè) Date 格式化為日期/時(shí)間字符串
public Date parse(String source)throws ParseException從給定字符串的開(kāi)始解析文本,以生成一個(gè)日期。

字符串轉(zhuǎn)成Date對(duì)象

//創(chuàng)建一個(gè)SimpleDateFormat并且告知它要讀取的字符串格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateFormat = "2019-05-31";//創(chuàng)建一個(gè)日期格式字符串
//將一個(gè)字符串轉(zhuǎn)換為相應(yīng)的Date對(duì)象
Date date = sdf.parse(dateFormat);//要先捕獲異常
System.out.println(date);//輸出這個(gè)Date對(duì)象

Date對(duì)象轉(zhuǎn)成字符串

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  
Date date = new Date(); 
String dateStr = sdf.format(date);//把日期對(duì)象傳進(jìn)去,繼承自DateFormat類(lèi)的方法。將一個(gè)Date格式化為日期/時(shí)間字符串

在日期格式中,-和空格無(wú)特殊意義。無(wú)特殊含義的都原樣輸出

//將當(dāng)前系統(tǒng)時(shí)間轉(zhuǎn)換為2012/05/14 17:05:22的效果
SimpleDateFormat format1 = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
dateStr=format1.format(date);
System.out.println(dateStr);
DateFormat類(lèi)

java.text.DateFormat類(lèi)(抽象類(lèi))是SimpleDateFormat類(lèi)的父類(lèi),用的少,沒(méi)SimpleDateFormat靈活。

java.sql.Date

java.sql.Date繼承java.util.Date,為了把前者轉(zhuǎn)為后者,需要以下代碼

Date date = new Date();
//java.sql.Date 不支持Date參數(shù)的構(gòu)造器,傳入long類(lèi)型的時(shí)間
java.sql.Date d = new java.sql.Date(date.getTime());
System.out.println(d);
System.out.println(d.getHours());

輸出結(jié)果

2019-05-31
Exception in thread "main" java.lang.IllegalArgumentException
    at java.sql.Date.getHours(Unknown Source)
    at DateTest.DateTest1.main(DateTest1.java:40)

這是由于java.sql.Date是SQL中的單純的日期類(lèi)型,沒(méi)有時(shí)分秒。故一般通過(guò)JDBC插入java.sql.Date數(shù)據(jù)時(shí),會(huì)發(fā)現(xiàn)時(shí)分秒都沒(méi)有。因此,如果同時(shí)需要日期和時(shí)間,應(yīng)該使用Timestamp。它也是 java.util.Date 的子類(lèi),Timestamp 則包含時(shí)間戳的完整信息。

java.sql.Timestamp是java.util.Date的派生類(lèi)(繼承),所以在java.util.Date上能做的事,也可以在java.sql.Timestamp上做。
如果當(dāng)前是2019-06-01 14:35,你創(chuàng)建一個(gè)java.sql.Date 將只記下2019-06-01這個(gè)信息。若你需要保留時(shí)間進(jìn)行JDBC操作,請(qǐng)使用java.sql.Timestamp代替。

long time = System.currentTimeMillis();
java.sql.Timestamp timestamp = new java.sql.Timestamp(time);
timestamp.setNanos(123456);
int nanos = timestamp.getNanos(); // nanos = 123456

現(xiàn)在的Date類(lèi)中大部分方法已經(jīng)棄用,現(xiàn)在一般使用舊的API,Date只負(fù)責(zé)存儲(chǔ)一個(gè)時(shí)間,并對(duì)Calendar和DateFormat提供操作接口。Calendar獲取Date中特定的信息,對(duì)日期時(shí)間進(jìn)行操作,SimpleDateFormat對(duì)日期時(shí)間進(jìn)行格式化輸入輸出。

總的來(lái)說(shuō),Date、Calendar 和 DateFormat 已經(jīng)能夠處理一般的時(shí)間日期問(wèn)題了。但是不可避免的是,它們依然很繁瑣,不好用并且這些日期類(lèi)都是可變且線程不安全的
Joda-Time

詳情請(qǐng)查看https://www.ibm.com/developer...

Java 8 時(shí)間日期API 特性

不變性:新的日期/時(shí)間API中,所有的類(lèi)都是不可變的,這對(duì)多線程很有好處。

關(guān)注點(diǎn)分離:借鑒了Joda庫(kù)的一些優(yōu)點(diǎn),新的API將人可讀的日期時(shí)間和機(jī)器時(shí)間(unix timestamp)明確分離,它為日期(Date)、時(shí)間(Time)、日期時(shí)間(DateTime)、時(shí)間戳(unix timestamp)以及時(shí)區(qū)定義了不同的類(lèi)。

清晰:在所有的類(lèi)中,方法都被明確定義用以完成相同的行為。例如要拿到當(dāng)前實(shí)例我們可以使用now()方法,在所有的類(lèi)中都定義了format()和parse()方法,而不是像以前那樣專(zhuān)門(mén)有一個(gè)獨(dú)立的類(lèi)。為了更好的處理問(wèn)題,所有的類(lèi)都使用了工廠模式和策略模式,一旦你使用了其中某個(gè)類(lèi)的方法,與其他類(lèi)協(xié)同工作并不困難。

實(shí)用操作:所有新的日期/時(shí)間API類(lèi)都實(shí)現(xiàn)了一系列方法用以完成通用的任務(wù),如:加、減、格式化、解析、從日期/時(shí)間中提取多帶帶部分,等等。

可擴(kuò)展性:新的日期/時(shí)間API是工作在ISO-8601日歷系統(tǒng)上的,但我們也可以將其應(yīng)用在非IOS的日歷上。

Java8日期時(shí)間的默認(rèn)格式如下:yyyy-MM-dd-HH-mm-ss.zzz

幾個(gè)主要的核心類(lèi):

LocalDate:日期類(lèi),不帶時(shí)間

LocalTime:時(shí)間類(lèi),不帶日期

LocalDateTime:日期和時(shí)間類(lèi)

ZonedDateTime:時(shí)區(qū)日期時(shí)間類(lèi)

OffsetDateTime:按UTC時(shí)間偏移來(lái)得到日期時(shí)間

Clock:獲取某個(gè)時(shí)區(qū)下當(dāng)前的瞬時(shí)時(shí)間,日期或者時(shí)間

Instant:Unix時(shí)間,代表時(shí)間戳,比如 2018-01-14T02:20:13.592Z

Duration:兩個(gè)時(shí)間之間,表示一個(gè)絕對(duì)的精確跨度,使用毫秒為單位

Period:兩個(gè)日期之間

ZoneId:時(shí)區(qū)

DateTimeFormatter:格式化輸出

TemporalAdjusters:獲得指定日期時(shí)間等,如當(dāng)月的第一天、今年的最后一天等等

下面看看這些類(lèi)具體如何使用

LocalDate、LocalTime、LocalDateTime

LocalDate是不變的日期時(shí)間對(duì)象代表一個(gè)日期,往往被視為年月日。其他日期字段,如一年中的一天,一周和一周的一天,也可以訪問(wèn)。例如,“2007年10月2日”的值可以被存儲(chǔ)在一個(gè)LocalDate。

LocalTime是不變的日期時(shí)間對(duì)象代表一個(gè)時(shí)間,往往被視為小時(shí)分鐘秒。時(shí)間為代表的納秒級(jí)精度。例如,值“13:45.30.123456789”可以存儲(chǔ)在一個(gè)LocalTime。

LocalDateTime是不變的日期時(shí)間對(duì)象代表一個(gè)日期時(shí)間,往往被視為年、月、日、時(shí)、分、秒。其他日期和時(shí)間字段,如一年中的一天,一周和一周的一天,也可以訪問(wèn)。時(shí)間為代表的納秒級(jí)精度。例如,值“2007年10月2日在13:45.30.123456789”可以存儲(chǔ)在一個(gè)LocalDateTime。

//now()在默認(rèn)時(shí)區(qū)中從系統(tǒng)時(shí)鐘獲取當(dāng)前日期。
LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); //等價(jià)于 today.plusWeeks(1)

//of(int year, int month, int dayOfMonth) 獲得 LocalDate實(shí)例從一年、月、日。 
LocalDate date = LocalDate.of(2019,5,31);
LocalTime time = LocalTime.of(20,31,20);

//of(LocalDate date, LocalTime time) 獲得 LocalDateTime實(shí)例的日期和時(shí)間。 
LocalDateTime dateTime = LocalDateTime.of(date,time);
System.out.println(dateTime);

//LocalDate結(jié)合LocalTime成一個(gè)LocalDateTime
LocalDateTime dateTime2 = date.atTime(time);
System.out.println(dateTime2); //2019-05-31T20:31:20
DateTimeFormatter

格式器用于解析日期字符串和格式化日期輸出,創(chuàng)建格式器最簡(jiǎn)單的方法是通過(guò) DateTimeFormatter 的靜態(tài)工廠方法以及常量。創(chuàng)建格式器一般有如下三種方式:

常用 ISO 格式常量,如 ISO_LOCAL_DATE

字母模式,如 ofPattern("yyyy/MM/dd")

本地化樣式,如 ofLocalizedDate(FormatStyle.MEDIUM)

和舊的 java.util.DateFormat 相比較,所有的 DateTimeFormatter 實(shí)例都是線程安全的。

使用DateTimeFormatter完成格式化

//獲取默認(rèn)時(shí)區(qū)中從系統(tǒng)時(shí)鐘獲取當(dāng)前日期時(shí)間。
LocalDateTime localDateTime = LocalDateTime.now();
//創(chuàng)建一個(gè)格式化程序使用指定的模式。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatDateTime = localDateTime.format(formatter);
System.out.println(formatDateTime);

//DateTimeFormatter提供了一些默認(rèn)的格式化器,DateTimeFormatter.ISO_LOCAL_DATE_TIME 格式 yyyy-MM-ddTHH:mm:ss.SSS
String dateTime2 = localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(dateTime2);

使用DateTimeFormatter完成解析字符串

//獲得 LocalDate實(shí)例,從使用特定格式的文本字符串解析,文字使用格式化程序解析,返回一個(gè)日期。
LocalDate localDate = LocalDate.parse("2018/11/11",DateTimeFormatter.ofPattern("yyyy/MM/dd"));
System.out.println(localDate); //2018-11-11
Instant

Instant 表示時(shí)間線上的一點(diǎn)(與 Date 類(lèi)似),它只是簡(jiǎn)單地表示自 1970 年 1 月 1 日 0 時(shí) 0 分 0 秒(UTC)開(kāi)始的秒數(shù)。

Instant 由兩部分組成,一是從原點(diǎn)開(kāi)始到指定時(shí)間點(diǎn)的秒數(shù) s, 二是距離該秒數(shù) s 的納秒數(shù)。它以 Unix 時(shí)間戳的形式存儲(chǔ)日期時(shí)間,不提供處理人類(lèi)意義上的時(shí)間單位(年月日等)。

你可以通過(guò)Instant類(lèi)的工廠方法創(chuàng)建一個(gè)Instant實(shí)例

//調(diào)用instant.now()來(lái)創(chuàng)建一個(gè)確切的表達(dá)當(dāng)前時(shí)間的Instant對(duì)象.另外也有一些其它方法能創(chuàng)建Instant,具體請(qǐng)查閱Java官方文檔。
Instant now = Instant.now();
Instant later = now.plusSeconds(3);
Instant earlier = now.minusSeconds(3);

//第一個(gè)參數(shù)是秒,第二個(gè)是納秒?yún)?shù),納秒的存儲(chǔ)范圍是0至999,999,999
//2s之后的在加上100萬(wàn)納秒(1s)
Instant instant = Instant.ofEpochSecond(2,1000000000);
System.out.println(instant); //1970-01-01T00:00:03Z

Instant instant1 = Instant.now();
System.out.println(instant1); //2019-05-31T16:19:28.719Z

Instant instant2 = Instant.parse("2018-11-11T10:12:35.342Z");
System.out.println(instant2); //2018-11-11T10:12:35.342Z

//java.util.Date與Instant可相互轉(zhuǎn)換
Instant timestamp = new Date().toInstant();
Date.from(Instant.now());

//為了更好的顯示,代碼改寫(xiě)為
Date date = new Date();
Instant timestamp = date.toInstant();
System.out.println(date);
System.out.println(timestamp);
Instant now1 = Instant.now();
Date date1 = Date.from(now1);
System.out.println(now1);
System.out.println(date1);
//輸出結(jié)果
Sat Jun 01 00:29:42 GMT+08:00 2019
2019-05-31T16:29:42.566Z
2019-05-31T16:29:42.588Z
Sat Jun 01 00:29:42 GMT+08:00 2019
Clock

Clock用于查找當(dāng)前時(shí)刻,可以用來(lái)獲取某個(gè)時(shí)區(qū)下當(dāng)前的日期和時(shí)間,也可以用來(lái)代替舊的System.currentTimeMillis()方法和TimeZone.getDefault()方法。

//返回系統(tǒng)默認(rèn)時(shí)間
Clock clock = Clock.systemDefaultZone();
System.out.println(clock.instant().toString());

//世界協(xié)調(diào)時(shí)UTC
Clock clock = Clock.systemUTC();  
//通過(guò)Clock獲取當(dāng)前時(shí)刻  
System.out.println("當(dāng)前時(shí)刻為:" + clock.instant());  
//獲取clock對(duì)應(yīng)的毫秒數(shù),與System.currentTimeMillis()輸出相同  
System.out.println(clock.millis());  
System.out.println(System.currentTimeMillis());  
Duration

一個(gè)Duration實(shí)例是不可變的,當(dāng)創(chuàng)建出對(duì)象后就不能改變它的值了。你只能通過(guò)Duration的計(jì)算方法,來(lái)創(chuàng)建出一個(gè)新的Durtaion對(duì)象。你會(huì)在之后的教程中見(jiàn)到的。一個(gè)Duration對(duì)象表示兩個(gè)Instant間的一段時(shí)間。

創(chuàng)建Duration實(shí)例,使用Duration類(lèi)的工廠方法來(lái)創(chuàng)建一個(gè)Duration對(duì)象

Instant first = Instant.now();
// wait some time while something happens
Instant second = Instant.now();
Duration duration = Duration.between(first, second);

//獲得Duration表示秒數(shù),然后獲得在此期間的分鐘數(shù)、小時(shí)數(shù)、天數(shù)
Duration d = Duration.ofSeconds(6000);  
System.out.println("6000秒相當(dāng)于" + d.toMinutes() + "分");  
System.out.println("6000秒相當(dāng)于" + d.toHours() + "小時(shí)");  
System.out.println("6000秒相當(dāng)于" + d.toDays() + "天");  

訪問(wèn)Duration的時(shí)間
一個(gè)Duration對(duì)象里有兩個(gè)域:納秒值(小于一秒的部分),秒鐘值(一共有幾秒),他們的組合表達(dá)了時(shí)間長(zhǎng)度。注意與使用System.getCurrentTimeMillis()時(shí)不同,Duration不包含毫秒這個(gè)屬性。
你可以通過(guò)以下兩個(gè)方法得到它們的值:getSeconds()和getNano()

Period

Period 是以年月日來(lái)衡量一個(gè)時(shí)間段,用于計(jì)算兩個(gè)日期間隔,所以 between() 方法只能接收 LocalDate 類(lèi)型的參數(shù)。

LocalDate start = LocalDate.of(2018, Month.JANUARY, 1);
LocalDate end = LocalDate.of(2020, Month.NOVEMBER, 11);
System.out.println("相隔月數(shù):"+Period.between(start, end).getMonths());
System.out.println("相隔天數(shù):"+Period.between(start, end).getDays());
//輸出結(jié)果
相隔月數(shù):10
相隔天數(shù):10

值得注意的是,Period 得到的是差值的絕對(duì)值(對(duì)應(yīng)年月日直接計(jì)算數(shù)學(xué)上的差值),而并不表示真正的區(qū)間距離。

long distanceMonth = start.until(end, ChronoUnit.MONTHS);
long  distanceDay= start.until(end, ChronoUnit.DAYS);
System.out.println("相隔月數(shù)"+distanceMonth);
System.out.println("相隔天數(shù)"+distanceDay);
//輸出結(jié)果
相隔月數(shù):34
相隔天數(shù):1045
ZonedDateTime和ZonedId

ZonedDateTime類(lèi)是Java 8中日期時(shí)間功能里,用于表示帶時(shí)區(qū)的日期與時(shí)間信息的類(lèi)。ZonedDateTime 類(lèi)的值是不可變的,所以其計(jì)算方法會(huì)返回一個(gè)新的ZonedDateTime 實(shí)例。

Java 使用 ZoneId 來(lái)標(biāo)識(shí)不同的時(shí)區(qū),從基準(zhǔn) UTC 開(kāi)始的一個(gè)固定偏移。

創(chuàng)建一個(gè)ZonedDateTime實(shí)例

//使用當(dāng)前時(shí)間作為值新建對(duì)象
ZonedDateTime dateTime = ZonedDateTime.now();

//使用指定的年月日、時(shí)分、納秒以及時(shí)區(qū)ID來(lái)新建對(duì)象
//時(shí)區(qū)是用ZoneId類(lèi)表示的,可以使用ZoneId.now()或ZoneId.of(“xxx”)來(lái)實(shí)例化:
//傳給of()方法的參數(shù)是時(shí)區(qū)的ID,如“UTC+1”指距離UTC(格林威治時(shí)間)有一小時(shí)的時(shí)差
ZoneId zoneId = ZoneId.of("UTC+1");
ZonedDateTime dateTime2 = ZonedDateTime.of(2019, 6, 1, 14, 40, 48, 1234, zoneId);

//也可以使用另一種方式表示zone id,即使用地區(qū)名字
ZoneId zoneId2 = ZoneId.of("Europe/Copenhagen");

//GregorianCalendar與ZonedDateTime相互轉(zhuǎn)換
ZonedDateTime zonedDateTime = new GregorianCalendar().toZonedDateTime();
GregorianCalendar.from(zonedDateTime);
TemporalAdjusters

有的時(shí)候,你需要進(jìn)行一些更加復(fù)雜的操作,比如,將日期調(diào)整到下個(gè)周日、下個(gè)工作日,或者是本月的最后一天。

簡(jiǎn)單應(yīng)用例子

LocalDate localDate = LocalDate.now();  
// 1. 本月第一天
LocalDate firstDayOfMonth = localDate.with(TemporalAdjusters.firstDayOfMonth());
// 2. 本月最后一天
LocalDate lastDayOfMonth = localDate.with(TemporalAdjusters.lastDayOfMonth());
// 3. 本年第一天
LocalDate firstDayOfYear = localDate.with(TemporalAdjusters.firstDayOfYear());
// 4. 下個(gè)月第一天
LocalDate firstDayOfNextMonth = localDate.with(TemporalAdjusters.firstDayOfNextMonth());
// 5. 本年度最后一天
LocalDate lastDayOfYear = localDate.with(TemporalAdjusters.lastDayOfYear());
System.out.println(firstDayOfMonth);
System.out.println(lastDayOfMonth);
System.out.println(firstDayOfYear);
System.out.println(firstDayOfNextMonth);
System.out.println(lastDayOfYear);

這時(shí),你可以使用重載版本的with方法,向其傳遞一個(gè)提供了更多定制化選擇的TemporalAdjuster對(duì)象,更加靈活地處理日期。TemporalAdjusters類(lèi)通過(guò)靜態(tài)方法提供了大量的常用的TemporalAdjuster的實(shí)現(xiàn)供我們使用。

/**
 * 時(shí)間校正器TemporalAdjuster
 */
@Test
public void Test() {
    LocalDateTime now1 = LocalDateTime.now();
    //獲取月中的第一天
    now1.with(TemporalAdjusters.firstDayOfMonth());
    //獲取下一年的第一天   
    now1.with(TemporalAdjusters.firstDayOfNextYear());
    //獲取年中第一天
    now1.with(TemporalAdjusters.lastDayOfYear());
    //獲取月中最后一天
    now1.with(TemporalAdjusters.lastDayOfMonth());
    //獲取下個(gè)星期一
    now1.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
    //自定時(shí)時(shí)間:下一個(gè)工作日,因?yàn)檫@里需要一個(gè)接口,所以完全可以自定義方法
    now1.with((e) -> {
        LocalDateTime now = (LocalDateTime)e; 
        DayOfWeek dow = now.getDayOfWeek();
        if (dow.equals(DayOfWeek.FRIDAY)) 
            return now.plusDays(3);
        else if (dow.equals(DayOfWeek.SATURDAY))
            return now.plusDays(2);
        return  now.plusDays(1);
    });
}
轉(zhuǎn)換 java.util.Date 與 LocalDate、LocalTime、LocalDateTime 轉(zhuǎn)換

將Date轉(zhuǎn)換為L(zhǎng)ocalDate,LocalTime,LocalDateTime可以借助于ZonedDateTime和Instant,實(shí)現(xiàn)如下:

Date date = new Date();
System.out.println("current date: " + date);

// Date -> LocalDateTime
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println("localDateTime by Instant: " + localDateTime);

// Date -> LocalDate
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
System.out.println("localDate by Instant: " + localDate);
// Date -> LocalTime
LocalTime localTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
System.out.println("localTime by Instant: " + localTime);

//2. Date -> LocalDateTime
localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
System.out.println("localDateTime by ofInstant: " + localDateTime);

由于JDK8實(shí)現(xiàn)了向下兼容,所以Date里在JDK8版本引入了2個(gè)方法,from和
toInstant,所以我們可以借助這兩個(gè)方法來(lái)實(shí)現(xiàn)LocalDateTime到Date的轉(zhuǎn)換。將LocalDateTime轉(zhuǎn)為Date如下:

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime: " + localDateTime);

// LocalDateTime -> Date
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
System.out.println("LocalDateTime -> current date: " + date);

// LocalDate -> Date,時(shí)間默認(rèn)都是00
LocalDate localDate = LocalDate.now();
date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println("LocalDate -> current date: " + date);
日期與字符串的轉(zhuǎn)換

通過(guò)LocalDate,LocalTime,LocalDateTime的parse方法和DateTimeFormatter來(lái)實(shí)現(xiàn):

//字符串->日期
LocalDate localDate = LocalDate.parse("2018-09-09", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDateTime localDateTime = LocalDateTime.parse("2018-09-10 12:12:12", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

//日期->字符串
String localDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
String localDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// 也可以通過(guò)DateTimeFormatter的format方法
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
localDateTime = dateTimeFormatter.format(LocalDateTime.now());
時(shí)間戳與LocalDateTime轉(zhuǎn)換

具體實(shí)現(xiàn)如下:

//時(shí)間戳->LocalDateTime
public static LocalDateTime convertToDate(long timestamp) {
   // ofEpochSecond 以秒為單位, ofEpochMilli 以毫秒為單位
   // Instant.ofEpochSecond(timestamp);
   Instant instant = Instant.ofEpochMilli(timestamp);
   return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}

//LocalDateTime->時(shí)間戳
public static long convertToTimestamp() {
   LocalDateTime localDateTime = LocalDateTime.now();
   return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
總結(jié)

所有新的日期時(shí)間 API 類(lèi)都實(shí)現(xiàn)了一系列方法用以完成通用的任務(wù),如:加、減、格式化、解析、從日期/時(shí)間中提取多帶帶部分。

Java 8 中新的時(shí)間與日期 API 中的所有類(lèi)都是不可變且線程安全的,任何修改操作都會(huì)返回一個(gè)新的實(shí)例。

新的 API 區(qū)分各種日期時(shí)間概念并且各個(gè)概念使用相似的方法定義模式,這種相似性非常有利于 API 的學(xué)習(xí)??偨Y(jié)一下一般的方法或者方法前綴:

of:靜態(tài)工廠方法,用于創(chuàng)建實(shí)例

now:靜態(tài)工廠方法,用當(dāng)前時(shí)間創(chuàng)建實(shí)例

parse:靜態(tài)工廠方法,從字符串解析得到對(duì)象實(shí)例

get:獲取時(shí)間日期對(duì)象的部分狀態(tài)。

is:檢查某些東西的是否是 true,例如比較時(shí)間前后

with:返回一個(gè)部分狀態(tài)改變了的時(shí)間日期對(duì)象拷貝

plus:返回一個(gè)時(shí)間增加了的、時(shí)間日期對(duì)象拷貝

minus:返回一個(gè)時(shí)間減少了的、時(shí)間日期對(duì)象拷貝

to:轉(zhuǎn)換到另一個(gè)類(lèi)型

at:把這個(gè)對(duì)象與另一個(gè)對(duì)象組合起來(lái),例如 date.atTime(time)

format:提供格式化時(shí)間日期對(duì)象的能力

更多方法使用請(qǐng)參考Java api文檔

參考文章:

http://www.importnew.com/1414...

https://docs.oracle.com/javas...

https://www.jianshu.com/p/f4a...

文章同步發(fā)表在個(gè)人博客kiwen的博客

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/74736.html

相關(guān)文章

  • Java? 教程(Date-Time)

    Date-Time Java SE 8發(fā)行版中引入的Date-Time包java.time提供了全面的日期和時(shí)間模型,是在JSR 310:Date and Time API下開(kāi)發(fā)的,盡管java.time基于國(guó)際標(biāo)準(zhǔn)化組織(ISO)日歷系統(tǒng),但也支持常用的全球日歷。 此課程介紹了使用基于ISO的類(lèi)來(lái)表示日期和時(shí)間以及操作日期和時(shí)間值的基本原理。 概述 時(shí)間似乎是一個(gè)簡(jiǎn)單的主題,即便是便宜的手表也能...

    AlphaGooo 評(píng)論0 收藏0
  • Java? 教程(目錄)

    Java? 教程 Java教程是為JDK 8編寫(xiě)的,本頁(yè)面中描述的示例和實(shí)踐沒(méi)有利用在后續(xù)版本中引入的改進(jìn)。 Java教程是希望使用Java編程語(yǔ)言創(chuàng)建應(yīng)用程序的程序員的實(shí)用指南,其中包括數(shù)百個(gè)完整的工作示例和數(shù)十個(gè)課程,相關(guān)課程組被組織成教程。 覆蓋基礎(chǔ)知識(shí)的路徑 這些教程以書(shū)籍的形式提供,如Java教程,第六版,前往Amazon.com購(gòu)買(mǎi)。 入門(mén) 介紹Java技術(shù)和安裝Java開(kāi)發(fā)軟件并使用...

    lifesimple 評(píng)論0 收藏0
  • Java8實(shí)戰(zhàn)》-第十二章筆記(新的日期時(shí)間API

    摘要:合并日期和時(shí)間這個(gè)復(fù)合類(lèi)名叫,是和的合體。截至目前,我們介紹的這些日期時(shí)間對(duì)象都是不可修改的,這是為了更好地支持函數(shù)式編程,確保線程安全,保持領(lǐng)域模式一致性而做出的重大設(shè)計(jì)決定。 新的日期和時(shí)間API Java的API提供了很多有用的組件,能幫助你構(gòu)建復(fù)雜的應(yīng)用。不過(guò),Java API也不總是完美的。我們相信大多數(shù)有經(jīng)驗(yàn)的程序員都會(huì)贊同Java 8之前的庫(kù)對(duì)日期和時(shí)間的支持就非常不理想...

    khlbat 評(píng)論0 收藏0
  • 20 個(gè)案例教你在 Java 8 中如何處理日期時(shí)間?

    摘要:前言前面一篇文章寫(xiě)了如何安全的使用里面介紹了如何處理日期時(shí)間,以及如何保證線程安全,及其介紹了在中的處理時(shí)間日期默認(rèn)就線程安全的類(lèi)。引入了全新的日期時(shí)間格式工具,線程安全而且使用方便。 前言 前面一篇文章寫(xiě)了《SimpleDateFormat 如何安全的使用?》, 里面介紹了 SimpleDateFormat 如何處理日期/時(shí)間,以及如何保證線程安全,及其介紹了在 Java 8 中的處...

    Rango 評(píng)論0 收藏0
  • Java8新特性之日期處理

    摘要:處理日期日歷和時(shí)間的不足之處將設(shè)定為可變類(lèi)型,以及的非線程安全使其應(yīng)用非常受限。最完整的日期時(shí)間,包含時(shí)區(qū)和相對(duì)或格林威治的時(shí)差。獲取當(dāng)前的日期中的用于表示當(dāng)天日期。 簡(jiǎn)介 伴隨 lambda表達(dá)式、streams 以及一系列小優(yōu)化,Java 8 推出了全新的日期時(shí)間API。 Java處理日期、日歷和時(shí)間的不足之處:將 java.util.Date 設(shè)定為可變類(lèi)型,以及 SimpleD...

    Airy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<