Java中時間API使用詳解

来源:https://www.cnblogs.com/54chensongxia/archive/2019/09/11/11509159.html
-Advertisement-
Play Games

Java中時間API使用詳解 [TOC] 1. 時區概念 國際經度會議(又稱國際子午線會議)上,規定將全球劃分為24個時區(東、西各12個時區)。規定英國的格林尼治天文臺舊址為中時區(零時區)、東1 12區,西1 12區。每個時區橫跨經度15度,時間正好是1小時。最後的東、西第12區各跨經度7.5度 ...


目錄

Java中時間API使用詳解



1. 時區概念

國際經度會議(又稱國際子午線會議)上,規定將全球劃分為24個時區(東、西各12個時區)。規定英國的格林尼治天文臺舊址為中時區(零時區)、東1-12區,西1-12區。每個時區橫跨經度15度,時間正好是1小時。最後的東、西第12區各跨經度7.5度,以東、西經180度為界。每個時區的中央經線上的時間就是這個時區內統一採用的時間,稱為區時,相鄰兩個時區的時間相差1小時。英國(格林尼治天文臺舊址)為本初子午線,即零度經線。

時區的表格劃分

為什麼全世界不使用統一的時間

於各個地區所在地球位置不同,所處地球的經度不同,故其日出日落的時間也不相同。在地球上劃定不同的時區,是為了使時間和自然現象(白天黑夜)有固定的對應。如果全世界用統一的時間,那麼中國的8:00是早上,而美國的8:00卻是晚上了。這樣容易擾亂人自身生理的節律和對日常生活的安排也及其不方便。人是不能改變白天黑夜的,只好改變衡量白天黑夜的辦法了。

2. 幾種常見的時間

  1. GMT
    GMT(格林威治標準時間):也就是0時區的時間,理論上來說,格林尼治標準時間的正午是指當太陽橫穿格林尼治子午線時(也就是在格林尼治上空最高點時)的時間。由於地球在它的橢圓軌道里的運動速度不均勻,這個時刻可能和實際的太陽時相差16分鐘。地球每天的自轉是有些不規則的,而且正在緩慢減速。所以,格林尼治時間已經不再被作為標準時間使用。現在的標準時間——協調世界時(UTC)——由原子鐘提供。

  2. UTC
    UTC(世界協調時間),協調世界時是以原子時秒長為基礎,國際原子時的準確度為每日數納秒,而世界時的準確度為每日數毫秒,現在我們使用的互聯網就採用該計時標準。UTC是GMT微調過的時間,我們可以認為兩者是一致的。

  3. CET
    歐洲中部時間(CET)比世界標準時間(UTC)早一個小時,部分歐洲國家和北非國家使用,這個標準是地理加政治的產物;

  4. CST
    北京時間

    CET=UTC(GMT) + 1小時
    CST=UTC(GMT) + 8小時

3. 時間戳

時間戳是指格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至現在的總秒數(Java中獲得的秒數是以毫秒為單位的)。

例如現在北京時間2015-12-31 17:00:00的時間戳是1451552400,就是指從北京時間1970-01-01 08:00:00到2015-12-31 17:00:00已經過去了1451552400秒。

使用時間戳有如下好處:

  • 時間戳沒有時區概念,比如如果用'2015-12-31 17:00:00'這麼一個字元串表示時間的話,北京時間和美國時間是不一樣的,但是用時間戳1451552400來表示的話,那就是一定是唯一的時間,不會有歧義;
  • 時間戳在編程語言中一般是長整形數據類型,無論何種編程語言都能認識時間戳,如果用字元串表示時間,還需要轉換。

4. Java中的時間API

在Java8以前操作時間的常見API有:

  • java.util.Date:表示Java中的日期,但是能夠操作到時間級別,如今這個類中的很多方法都已經被廢棄,不建議使用;
  • java.sql.Date:表示資料庫時間,只能操作到日期,不能讀取和修改時間;
  • java.sql.Time:表示資料庫時間;
  • java.sql.Timestamp:時間戳;
  • Calendar:工具類,提供時間的加減等複雜操作,支持時區;
  • TimeZone:表示時區;
  • SimpleDateFormat:日期格式化類,非常常用。

Date主要負責存儲一個絕對時間,並對兩邊提供操作介面。Calendar負責對Date中特定信息,比如這個時間是該年的第幾個星期,此外,還可以通過set,add,roll介面來進行日期時間的增減。SimpleDateFormat主要作為一些格式化的輸入輸出。

4.1 Date的簡單列子

Date類比較簡單,支持兩種構造函數。不建議用這個類進行複雜的操作。如果使用的是Java8,建議使用LocalDate。Date類也提供了和Java 8 API相互轉換的介面。

Date date1 = new Date();
Thread.sleep(1000);
long nowTime = System.currentTimeMillis();
Date date2 = new Date(nowTime);
//Date類和Java 8 API相互轉換的介面
Instant instant = date2.toInstant();
Date date3 = Date.from(instant);

System.out.println("nowTime:"+nowTime);
System.out.println(date1);
System.out.println(date2);
System.out.println(date3);
System.out.println(date2.getTime());

4.2 SimpleDateFormat使用列子

SimpleDateFormat接收一個String pattern和Local參數來構造對象。其中pattern是預定義的:

G    年代標誌符
y    年
M   月
d    日
h    時 在上午或下午 (1~12)
H    時 在一天中 (0~23)
m   分
s    秒
S    毫秒
E    星期
D    一年中的第幾天
F    一月中第幾個星期幾
w   一年中第幾個星期
W   一月中第幾個星期
a    上午 / 下午 標記符 
k    時 在一天中 (1~24)
K   時 在上午或下午 (0~11)
z    時區
//預設的方言
SimpleDateFormat sf = new SimpleDateFormat("G yyyy-MM-dd a z");
SimpleDateFormat sf1 = new SimpleDateFormat("G yyyy-MM-dd a z", Locale.US);
SimpleDateFormat sf2 = new SimpleDateFormat("G yyyy-MM-dd a z", Locale.KOREA);
String format1 = sf.format(date1);
String format2 = sf1.format(date1);
String format3 = sf2.format(date1);
System.out.println("format1:"+format1);
System.out.println("format2:"+format2);
System.out.println("format3:"+format3);
//解析Date
Date date = sf.parse(format1);

4.3 Calendar的使用

Calendar還有許多其他API,比如獲得當前月天數,當前年天數等等,需要時可以查詢使用。

Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
// 獲取月,這裡需要需要月份的範圍為0~11,因此獲取月份的時候需要+1才是當前月份值
int month = calendar.get(Calendar.MONTH) + 1;
// 獲取日
int day = calendar.get(Calendar.DAY_OF_MONTH);
// 獲取時
int hour = calendar.get(Calendar.HOUR);
// 獲取分
int minute = calendar.get(Calendar.MINUTE);
// 獲取秒
int second = calendar.get(Calendar.SECOND);
System.out.println("現在是" + year + "年" + month + "月" + day + "日" + hour
        + "時" + minute + "分" + second + "秒");
//獲取一個月後的今天
calendar.add(Calendar.MONTH,1);

4.4 存在的問題

  • java的日期/時間類的定義並不一致,在java.util和java.sql的包中都有日期類,此外用於格式化和解析的類在java.text包中定義。
  • java.util.Date同時包含日期和時間,而java.sql.Date僅包含日期,將其納入java.sql包並不合理。另外這兩個類都有相同的名字,這本身就是一個非常糟糕的設計。
  • 對於時間、時間戳、格式化以及解析,並沒有一些明確定義的類。對於格式化和解析的需求,我們有java.text.DateFormat抽象類,但通常情況下,SimpleDateFormat類被用於此類需求。
  • 所有的日期類都是可變的,因此他們都不是線程安全的,這是Java日期類最大的問題之一。
  • 日期類並不提供國際化,沒有時區支持,因此Java引入了java.util.Calendar和java.util.TimeZone類,但他們同樣存在上述所有的問題。

5. Java8中新添加的時間API

  • java.time包:這是新的Java日期/時間API的基礎包,所有的主要基礎類都是這個包的一部分,如:LocalDate, LocalTime, LocalDateTime, Instant, Period, Duration等等。所有這些類都是不可變的和線程安全的,在絕大多數情況下,這些類能夠有效地處理一些公共的需求。
  • java.time.chrono包:這個包為非ISO的日曆系統定義了一些泛化的API,我們可以擴展AbstractChronology類來創建自己的日曆系統。
  • java.time.format包:這個包包含能夠格式化和解析日期時間對象的類,在絕大多數情況下,我們不應該直接使用它們,因為java.time包中相應的類已經提供了格式化和解析的方法。
  • java.time.temporal包:這個包包含一些時態對象,我們可以用其找出關於日期/時間對象的某個特定日期或時間,比如說,可以找到某月的第一天或最後一天。你可以非常容易地認出這些方法,因為它們都具有“withXXX”的格式。
  • java.time.zone包:這個包包含支持不同時區以及相關規則的類。

5.1 LocalDate

//Current Date
LocalDate today = LocalDate.now();
System.out.println("Current Date="+today);

//Creating LocalDate by providing input arguments
LocalDate firstDay_2014 = LocalDate.of(2014, Month.JANUARY, 1);
System.out.println("Specific Date="+firstDay_2014);

//Try creating date by providing invalid inputs
//LocalDate feb29_2014 = LocalDate.of(2014, Month.FEBRUARY, 29);
//Exception in thread "main" java.time.DateTimeException:
//Invalid date 'February 29' as '2014' is not a leap year

//Current date in "Asia/Kolkata", you can get it from ZoneId javadoc
LocalDate todayKolkata = LocalDate.now(ZoneId.of("Asia/Kolkata"));
System.out.println("Current Date in IST="+todayKolkata);

//Getting date from the base date i.e 01/01/1970
LocalDate dateFromBase = LocalDate.ofEpochDay(365);
System.out.println("365th day from base date= "+dateFromBase);

//2014年的第100天
LocalDate hundredDay2014 = LocalDate.ofYearDay(2014, 100);
System.out.println("100th day of 2014="+hundredDay2014);

5.2 LocalTime使用

//Current Time
LocalTime time = LocalTime.now();
System.out.println("Current Time="+time);

//Creating LocalTime by providing input arguments
LocalTime specificTime = LocalTime.of(12,20,25,40);
System.out.println("Specific Time of Day="+specificTime);

//Try creating time by providing invalid inputs
//LocalTime invalidTime = LocalTime.of(25,20);
//Exception in thread "main" java.time.DateTimeException:
//Invalid value for HourOfDay (valid values 0 - 23): 25

//Current date in "Asia/Kolkata", you can get it from ZoneId javadoc
LocalTime timeKolkata = LocalTime.now(ZoneId.of("Asia/Kolkata"));
System.out.println("Current Time in IST="+timeKolkata);

//java.time.zone.ZoneRulesException: Unknown time-zone ID: IST
//LocalTime todayIST = LocalTime.now(ZoneId.of("IST"));

//Getting date from the base date i.e 01/01/1970
LocalTime specificSecondTime = LocalTime.ofSecondOfDay(10000);
System.out.println("10000th second time= "+specificSecondTime);

5.3 LocalDateTime

//Current Date
LocalDateTime today = LocalDateTime.now();
System.out.println("Current DateTime="+today);

//Current Date using LocalDate and LocalTime
today = LocalDateTime.of(LocalDate.now(), LocalTime.now());
System.out.println("Current DateTime="+today);

//Creating LocalDateTime by providing input arguments
LocalDateTime specificDate = LocalDateTime.of(2014, Month.JANUARY, 1, 10, 10, 30);
System.out.println("Specific Date="+specificDate);

//Try creating date by providing invalid inputs
//LocalDateTime feb29_2014 = LocalDateTime.of(2014, Month.FEBRUARY, 28, 25,1,1);
//Exception in thread "main" java.time.DateTimeException:
//Invalid value for HourOfDay (valid values 0 - 23): 25

//Current date in "Asia/Kolkata", you can get it from ZoneId javadoc
LocalDateTime todayKolkata = LocalDateTime.now(ZoneId.of("Asia/Kolkata"));
System.out.println("Current Date in IST="+todayKolkata);

//java.time.zone.ZoneRulesException: Unknown time-zone ID: IST
//LocalDateTime todayIST = LocalDateTime.now(ZoneId.of("IST"));

//Getting date from the base date i.e 01/01/1970
LocalDateTime dateFromBase = LocalDateTime.ofEpochSecond(10000, 0, ZoneOffset.UTC);
System.out.println("10000th second time from 01/01/1970= "+dateFromBase);

5.4 Instant

Instant可以理解為時間戳。

//Current timestamp
Instant timestamp = Instant.now();
System.out.println("Current Timestamp = "+timestamp);

//Instant from timestamp
Instant specificTime = Instant.ofEpochMilli(timestamp.toEpochMilli());
System.out.println("Specific Time = "+specificTime);

//Duration example
Duration thirtyDay = Duration.ofDays(30);
System.out.println(thirtyDay);

5.5 格式化

需要格式化日期時,我們直接調用相關類的format方法即可,如下:

//DateTimeFormatter支持的模式和SimpleDateFormat支持的一致
today.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));

5.6 對舊時間API的支持

    Date date= new Date();Instant instant = date.toInstant();LocalDateTime pst = LocalDateTime.ofInstant(instant, 
    ZoneId.of(ZoneId.SHORT_IDS.get("PST")));Calendar calendar = Calendar.getInstance();Instant instant1 = calendar.toInstant();LocalDateTime pst1 = LocalDateTime.ofInstant(instant, 
    ZoneId.of(ZoneId.SHORT_IDS.get("PST")));

6. 在東八區的機器上獲得美國時間

美國屬於西5區,比北京時間晚13個小時。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 房天下 登錄 本次爬取的網址為: 一、分析請求 輸入用戶名和密碼,點擊登錄按鈕 請求的參數為: 就是輸入的用戶名, 是將密碼加密後的數據。我們只要找出密碼的加密方式就可以模擬登錄了。 二、密碼加密方式破解 這次我們以 作為關鍵字,進行搜索 找到加密位置之後,我們打上斷點,重新點擊登錄 找到密碼加密的 ...
  • 內容來自轉載整理 1.NumPy數值計算 NumPy是使用Python進行科學計算的基礎包,Numpy可以提供數組支持以及相應的高效處理函數,是Python數據分析的基礎,也是SciPy、Pandas等數據處理和科學計算庫最基本的函數功能庫,且其數據類型對Python數據分析十分有用。它包含: 一個 ...
  • 面試題 如何設計一個高併發系統? 面試官心理分析 說實話,如果面試官問你這個題目,那麼你必須要使出全身吃奶勁了。為啥?因為你沒看到現在很多公司招聘的 JD 里都是說啥,有高併發就經驗者優先。 如果你確實有真才實學,在互聯網公司里乾過高併發系統,那你確實拿 offer 基本如探囊取物,沒啥問題。面試官 ...
  • 前言 先列出java併發涉及的知識點,後面再慢慢補. java併發 1 常見概念 進程:程式執行的實體,操作系統資源調度資源分配的基本單元 線程:程式執行的最小單元,擁有獨立的堆棧和局部變數等屬性,可以共用進程的資源 同步是串列執行,阻塞 非同步是並行執行,非阻塞 併發:多個任務交替執行 並行:多個任 ...
  • 學習Python的第一天,也是我第一次寫博客的一天,不怎麼會寫博客,也不怎麼會Python,也不怎麼會寫總結.在學Python的第一天發現自己腦子不是很好用,在學習過程中出現很多錯誤,錯誤錦集如下,哈哈哈哈,要加油.以後要註意不要再犯下麵的錯誤了,不然以後在工作中很難獨立完成,也容易出現很多錯誤,這 ...
  • 之前多篇文章從mysql的底層結構分析、sql語句的分析器以及sql從優化底層分析, 還有工作中常用的sql優化小知識點。面試各大互聯網公司必問的mysql鎖和事務隔離級別,這篇文章給你打神助攻,一飛衝天。 鎖定義 鎖是電腦協調多個進程或線程併發訪問某一資源的機制。 在資料庫中,除了傳統的計算資源 ...
  • 一、instanceof運算符 instanceof是Java語言中的一個二元運算符,它的作用是判斷一個引用類型的變數所指向的對象是否是一個類(或介面、抽象類、父類)的實例,即它左邊的對象是否是它右邊的類的實例該運算符返回boolean類型的數據。 常見的用法為:result=object inst ...
  • [TOC] 原文鏈接: "QRowTable表格控制項(四) 效率優化之 優化數據源" 一、開心一刻 一程式員第一次上女朋友家她媽板著臉問 :你想娶我女兒,有多少存款? 程式員低了下頭:五百! 她媽更鄙視了:才五百塊,買個廁所都不夠! 程式員忙說:不是人民幣! 她媽:就算是美元,還是不夠買廁所! 程式 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...