亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Java中的時間日期API知識點總結

2024-07-14 08:40:16
字體:
來源:轉載
供稿:網友

自從 14 年發布 Java 8 以后,我們古老 java.util.Date 終于不再是我們 Java 里操作日期時間的唯一的選擇。

其實 Java 里的日期時間的相關 API 一直為世猿詬病,不僅在于它設計分上工不明確,往往一個類既能處理日期又能處理時間,很混亂,還在于某些年月日期的數值映射存儲反人類,例如:0 對應月份一月,11 對應月份十二月,118 對應年份 2018(1900 + 118)等。

往往我們得到某個年月值還需要再做相應的運算才能得到準確的年月日信息,直到我們的 Java 8 ,借鑒了第三方開源庫 Joda-Time 的優秀設計,重新設計了一個日期時間 API,相比之前,可以說好用百倍,相關 API 接口全部位于包 java.time 下。

古老的日期時間接口

表示時刻信息的 Date

世界上所有的計算機內部存儲時間都使用一個 long 類型的整數,而這個整數的值就是相對于英國格林尼治標準時間(1970年1月1日0時0分0秒)的毫秒數。例如:

public static void main(String[] args){  //January 1, 1970 00:00:00 GMT.  Date date = new Date(1000);  System.out.println(date);}

輸出結果:

//1970-1-1 8:00:01Thu Jan 01 08:00:01 CST 1970

很多人可能會疑惑,1000 表示的是距離標準時間往后 1 秒,那為什么時間卻多走了 八個小時?

這和「時區」有關系,如果你位于英國的格林尼治區,那么結果會如預想一樣,但是我們位于中國東八區,時間要早八個小時,所以不同時區基于的基礎值不同。

Date 這個類以前真的扮演過很多角色,從它的源碼就可以看出來,有可以操作時刻的方法,有可以操作年月日的方法,甚至它還能管時區??梢哉f,日期時間的相關操作有它一個人就足夠了。

但這個世界就是這樣,你管的東西多了,自然就不能面面俱到,Date 中很多方法的設計并不是很合理,之前我們也說了,甚至有點反人類。所以,現在的 Date 類中接近百分之八十的方法都已廢棄,被標記為 @Deprecated。

sun 公司給 Date 的目前定位是,唯一表示一個時刻,所以它的內部應該圍繞著那個整型的毫秒,而不再著重于各種年歷時區等信息。

Date 允許通過以下兩種構造器實例化一個對象:

private transient long fastTime;public Date() {  this(System.currentTimeMillis());}public Date(long date) {  fastTime = date;}

這里的 fastTime 屬性存儲的就是時刻所對應的毫秒數,兩個構造器還是很簡單,如果調用的是無參構造器,那么虛擬機將以系統當前的時刻值對 fastTime 進行賦值。

還有幾個為數不多沒有被廢棄的方法:

  • public long getTime() :返回內部存儲的毫秒數
  • public void setTime(long time):重新設置內存的毫秒數
  • public boolean before(Date when):比較給定的時刻是否早于當前 Date 實例
  • public boolean after(Date when):比較給定的時刻是否晚于當前 Date 實例

還有兩個方法是 jdk1.8 以后新增的,用于向 Java 8 新增接口的轉換,待會介紹。

 描述年歷的 Calendar

Calendar 用于表示年月日等日期信息,它是一個抽象類,所以一般通過以下四種工廠方法獲取它的實例對象。

public static Calendar getInstance()public static Calendar getInstance(TimeZone zone)public static Calendar getInstance(Locale aLocale)public static Calendar getInstance(TimeZone zone,Locale aLocale)

其實內部最終會調用同一個內部方法:

private static Calendar createCalendar(TimeZone zone,Locale aLocale)

該方法需要兩個參數,一個是時區,一個是國家和語言,也就是說,構建一個 Calendar 實例最少需要提供這兩個參數信息,否則將會使用系統默認的時區或語言信息。

因為不同的時區與國家語言對于時刻和年月日信息的輸出是不同的,所以這也是為什么一個 Calendar 實例必須傳入時區和國家信息的一個原因。看個例子:

public static void main(String[] args){  Calendar calendar = Calendar.getInstance();  System.out.println(calendar.getTime());  Calendar calendar1 = Calendar.getInstance      (TimeZone.getTimeZone("GMT"), Locale.ENGLISH);  System.out.println( calendar1.get(Calendar.YEAR) + ":" +            calendar1.get(Calendar.HOUR) + ":" +            calendar1.get(Calendar.MINUTE));  }

輸出結果:

Sat Apr 21 10:32:20 CST 20182018:2:32

可以看到,第一個輸出為我們系統默認時區與國家的當前時間,而第二個 Calendar 實例我們指定了它位于格林尼治時區(0 時區),結果也顯而易見了,相差了八個小時,那是因為我們位于東八區,時間早于 0 時區八個小時。

可能有人會疑惑了,為什么第二個 Calendar 實例的輸出要如此復雜的拼接,而不像第一個 Calendar 實例那樣直接調用 getTime 方法簡潔呢?

這涉及到 Calendar 的內部實現,我們一起看看:

protected long     time;public final Date getTime() {  return new Date(getTimeInMillis());}

和 Date 一樣,Calendar 的內部也維護著一個時刻信息,而 getTime 方法實際上是根據這個時刻構建了一個 Date 對象并返回的。

而一般我們構建 Calendar 實例的時候都不會傳入一個時刻信息,所以這個 time 的值在實例初始化的時候,程序會根據系統默認的時區和當前時間計算得到一個毫秒數并賦值給 time。

所以,所有未手動修改 time 屬性值的 Calendar 實例的內部,time 的值都是當時系統默認時區的時刻數值。也就是說,getTime 的輸出結果是不會理會當前實例所對應的時區信息的,這也是我覺得 Calendar 設計的一個缺陷所在,因為這樣會導致兩個不同時區 Calendar 實例的 getTime 輸出值只取決于實例初始化時系統的運行時刻。

Calendar 中也定義了很多靜態常量和一些屬性數組:

public final static int ERA = 0;public final static int YEAR = 1;public final static int MONTH = 2;public final static int WEEK_OF_YEAR = 3;public final static int WEEK_OF_MONTH = 4;public final static int DATE = 5;....protected int      fields[];protected boolean    isSet[];...

有關日期的所有相關信息都存儲在屬性數組中,而這些靜態常量的值往往表示的就是一個索引值,通過 get 方法,我們傳入一個屬性索引,返回得到該屬性的值。例如:

Calendar myCalendar = Calendar.getInstance();int year = myCalendar.get(Calendar.YEAR);

這里的 get 方法實際上就是直接取的 fields[1] 作為返回值,而 fields 屬性數組在 Calendar 實例初始化的時候就已經由系統根據時區和語言計算并賦值了,注意,這里會根據你指定的時區進行計算,它不像 time 始終是依照的系統默認時區。

個人覺得 Calendar 的設計有優雅的地方,也有不合理的地方,畢竟是個「古董」了,終將被替代。

DateFormat 格式化轉換

從我們之前的一個例子中可以看到,Calendar 想要輸出一個預期格式的日期信息是很麻煩的,需要自己手動拼接。而我們的 DateFormat 就是用來處理格式化字符串和日期時間之間的轉換操作的。

DateFormat 和 Calendar 一樣,也是一個抽象類,我們需要通過工廠方式產生其實例對象,主要有以下幾種工廠方法:

//只處理時間的轉換public final static DateFormat getTimeInstance()//只處理日期的轉換public final static DateFormat getDateInstance()//既可以處理時間,也可以處理日期public final static DateFormat getDateTimeInstance()

當然,它們各自都有各自的重載方法,具體的我們待會兒看。

DateFormat 有兩類方法,format 和 parse。

public final String format(Date date)public Date parse(String source)

format 方法用于將一個日期對象格式化為字符串,parse 方法用于將一個格式化的字符串裝換為一個日期對象。例如:

public static void main(String[] args){  Calendar calendar = Calendar.getInstance();  DateFormat dateFormat = DateFormat.getDateTimeInstance();  System.out.println(dateFormat.format(calendar.getTime()));}

輸出結果:

2018-4-21 16:58:09

顯然,使用工廠構造的 DateFormat 實例并不能夠自定義輸出格式化內容,即輸出的字符串格式是固定的,不能滿足某些情況下的特殊需求。一般我們會直接使用它的一個實現類,SimpleDateFormat。

SimpleDateFormat 允許在構造實例的時候傳入一個 pattern 參數,自定義日期字符的輸出格式。例如:

public static void main(String[] args){    DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");  System.out.println(dateFormat.format(new Date()));}

輸出結果:

2018年04月21日

其中,

  • yyyy:年份用四位進行輸出
  • MM:月份用兩位進行輸出
  • dd:兩位表示日信息
  • HH:兩位來表示小時數
  • mm:兩位表示分鐘數
  • ss:兩位來表示秒數
  • E:表示周幾,如果 Locale 在中國則會輸出 星期x,如果在美國或英國則會輸出英文的星期
  • a:表示上午或下午

當然,對于字符串轉日期也是很方便的,允許自定義模式,但必須遵守自己制定的模式,否則程序將無法成功解析。例如:

public static void main(String[] args){  String str = "2018年4月21日 17點17分 星期六";  DateFormat sDateFormat = new SimpleDateFormat("yyyy年M月dd日 HH點mm分 E");  sDateFormat.parse(str);  System.out.println(sDateFormat.getCalendar().getTime());}

輸出結果:

Sat Apr 21 17:17:00 CST 2018

顯然,程序是正確的解析的我們的字符串并轉換為 Calendar 對象存儲在 DateFormat 內部的。

總的來說,Date、Calendar 和 DateFormat 已經能夠處理一般的時間日期問題了,但是不可避免的是,它們依然很繁瑣,不好用。

限于篇幅,我們下篇將對比 Java 8 的新式日期時間 API,你會發現它更加優雅的設計和簡單的操作性。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
疯狂做受xxxx欧美肥白少妇| 亚洲天堂影视av| 91av视频在线播放| 国产精品免费久久久| 亚洲亚裔videos黑人hd| 亚洲国产精久久久久久久| 国模吧一区二区| 91精品国产成人| 国产日产欧美精品| 国产成人在线精品| 日韩视频免费在线观看| 亚洲a∨日韩av高清在线观看| 国产日韩欧美在线播放| 自拍偷拍亚洲在线| 久久久久久久久久久久久久久久久久av| 欧美成人午夜激情视频| 精品亚洲精品福利线在观看| 亚洲色图激情小说| 精品国产乱码久久久久久婷婷| 欧美高清在线观看| 国产精品视频一区国模私拍| 日韩小视频在线观看| 亚洲图片制服诱惑| 欧美黑人性生活视频| 久久全国免费视频| 国产日韩精品在线| 国产精品海角社区在线观看| 7777免费精品视频| 色综合伊人色综合网| 久久久久久999| 久久久99久久精品女同性| 国产香蕉一区二区三区在线视频| 亚州欧美日韩中文视频| 久久影视电视剧免费网站清宫辞电视| 亚洲成人久久电影| 欧美—级高清免费播放| 国产精品海角社区在线观看| 欧美精品videossex性护士| 久久久国产精彩视频美女艺术照福利| 亚洲欧美日韩网| 国产精品福利网站| 久久久久久久久久久网站| 亚洲а∨天堂久久精品9966| 日韩中文字幕网| 成人精品在线视频| 国产一区香蕉久久| 国产不卡视频在线| 成人亚洲欧美一区二区三区| 国产精品福利无圣光在线一区| 国产精品久久久久久久久久新婚| 日韩在线观看免费av| 91国产高清在线| 亚洲一区二区三区在线视频| 亚洲人成电影在线播放| 91美女片黄在线观| 日韩中文字幕视频在线| 久久精品国产精品亚洲| 亚洲美女av在线播放| 亚洲国产精品电影在线观看| 亚洲xxxx妇黄裸体| 欧美性猛xxx| 中文国产成人精品久久一| 国产精品盗摄久久久| 欧美色视频日本高清在线观看| 国产成人精品在线观看| 插插插亚洲综合网| 精品国产鲁一鲁一区二区张丽| 亚洲视频在线观看免费| 中文在线资源观看视频网站免费不卡| 日韩欧美国产视频| 精品久久久精品| 国产精品成人久久久久| 国产婷婷成人久久av免费高清| 久久精品99久久久久久久久| 欧美日韩美女在线观看| 国产精品wwwwww| 欧美日韩国产精品专区| 久久精品久久久久久国产 免费| 91色在线视频| 亚洲男人第一网站| 色久欧美在线视频观看| 亚洲精品国产精品国自产观看浪潮| 久久久久久久久综合| 国产精品美女www爽爽爽视频| 欧美孕妇孕交黑巨大网站| 91禁国产网站| 成人妇女免费播放久久久| www.欧美精品一二三区| 欧美色videos| 久久精品视频一| 国产午夜精品理论片a级探花| 亚洲色图35p| 亚洲 日韩 国产第一| 亚洲一区二区三区毛片| 国产美女直播视频一区| 国产精品三级在线| 国产精品私拍pans大尺度在线| 91久久在线观看| 亚洲精品自拍偷拍| 国产精品中文字幕在线| 成人黄色片网站| 91精品久久久久久久久久入口| 欧美高清理论片| 精品久久久91| 亚洲精品国产品国语在线| 欧美猛交ⅹxxx乱大交视频| 成人有码在线视频| 97在线视频一区| 国产福利视频一区| 国产精品视频自在线| 久久久久久久久中文字幕| 欧美激情videoshd| 在线观看中文字幕亚洲| 人九九综合九九宗合| x99av成人免费| 正在播放亚洲1区| 日韩免费av在线| 欧美在线免费视频| 亚洲国产精品福利| 麻豆乱码国产一区二区三区| 亚洲欧美日韩精品久久亚洲区| 久久99国产精品久久久久久久久| 欧美精品videosex牲欧美| 精品国产91乱高清在线观看| 亚洲成**性毛茸茸| 中文字幕免费国产精品| 国产一级揄自揄精品视频| 久久av中文字幕| 欧美激情精品久久久久久久变态| 日韩av在线影院| 九九热99久久久国产盗摄| 国产精品视频中文字幕91| 国产精品91免费在线| 91久久国产综合久久91精品网站| 久久久免费精品视频| 欧美极品在线视频| 欧美在线免费视频| 中文字幕在线看视频国产欧美| 国产日产久久高清欧美一区| 日韩美女写真福利在线观看| 国产日韩欧美成人| 2019日本中文字幕| 国产视频精品一区二区三区| 亚洲第一级黄色片| 国内精品视频一区| 国产精品一区二区三区免费视频| 日本成人黄色片| 国产成人精品一区二区三区| 国精产品一区一区三区有限在线| 免费av在线一区| 日韩av在线电影网| 精品夜色国产国偷在线| 岛国av一区二区三区| 亚洲电影免费观看高清完整版在线| 亚洲性线免费观看视频成熟| 在线视频中文亚洲| 欧洲成人性视频| www.亚洲一二| 国产精品第一页在线| 欧美日韩日本国产| 亚洲国产精品久久久久秋霞蜜臀| 日韩精品视频在线观看网址| 久久久免费观看视频| 亚洲bt天天射|