日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

团队和做的直观图_直观,可靠的日期和时间处理,终于出现在Java中

發布時間:2023/12/14 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 团队和做的直观图_直观,可靠的日期和时间处理,终于出现在Java中 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

團隊和做的直觀圖

日期和時間的概念是許多應用程序的基礎。 諸如生日,租期,活動時間戳記和商店營業時間之類的東西都是基于日期和時間的,但是Java SE沒有很好的API來處理它們。 使用Java SE 8,有一組新的程序包-java.time-提供了結構良好的API以涵蓋日期和時間。

歷史

當Java在1.0版中首次啟動時,對日期和時間的唯一支持是java.util.Date類。 大多數開發人員注意到該類的第一件事是它不代表“日期”。 它所做的表示其實原因很簡單-在時間點瞬時基于精確到毫秒,從1970-01-01Z的時代測量。 但是,由于標準的toString()表單會在JVM的默認時區中顯示日期和時間,因此某些開發人員錯誤地認為它是可識別時區的類。

當需要改進1.1版時,Date類被認為無法修復。 結果,添加了新的API- java.util.Calendar 。 可悲的是,Calendar類并沒有比java.util.Date更好。 這些類面臨的一些問題是:

  • 可變的。 諸如日期和時間之類的類應該是不變的。
  • 抵消。 日期中的年份從1900開始,兩個類別中的月份都從零開始。
  • 命名。 日期不是“日期”。 日歷不是“日歷”。
  • 格式化。 格式化程序僅適用于Date ,不適用于Calendar ,并且不是線程安全的

在2001年左右, Joda-Time項目開始了。 Joda-Time的目的很簡單-為Java提供高質量的日期和時間庫。 花費了一段時間,但最終推出了Joda-Time 1.0版,它成為一個非常廣泛使用和流行的庫。 隨著時間的流逝,提供JDK之類的Joda-Time這樣的庫的需求不斷增長。 在來自巴西的Michael Nascimento Santos的幫助下,JSR-310開始了,正式的過程是為JDK創建和集成新的日期和時間API。

總覽

新的java.time API包含5個軟件包:

  • java.time-包含值對象的基本包
  • java.time.chrono-提供對不同日歷系統的訪問
  • java.time.format-允許格式化和解析日期和時間
  • java.time.temporal-低級框架和擴展功能
  • java.time.zone-時區支持類

大多數開發人員將主要使用基本和格式包,以及臨時包。 因此,盡管有68種新的公共類型,但是大多數開發人員只會積極使用其中的三分之一。

日期

LocalDate類是新API中最重要的類之一。 它是表示日期的不可變值類型。 沒有時間或時區的表示。

Joda-Time熟悉“本地”術語,該術語最初來自ISO-8601日期和時間標準 。 它特別涉及到缺少時區。 實際上,本地日期是對日期的描述,例如“ 2014年4月5日”。 該特定的本地日期將根據您在地球上的位置在時間軸上的不同點開始。 因此,本地日期將從澳大利亞在倫敦開始的10個小時開始,在舊金山開始的18小時開始。

LocalDate類旨在具有所有通常需要的方法:

LocalDate date = LocalDate.of(2014, Month.JUNE, 10); int year = date.getYear(); // 2014 Month month = date.getMonth(); // JUNE int dom = date.getDayOfMonth(); // 10 DayOfWeek dow = date.getDayOfWeek(); // Tuesday int len = date.lengthOfMonth(); // 30 (days in June) boolean leap = date.isLeapYear(); // false (not a leap year)

在示例中,我們看到一個使用工廠方法創建的日期(所有構造函數都是私有的)。 然后查詢一些基本信息。 請注意, MonthDayOfWeek枚舉旨在使代碼更具可讀性和可靠性。

在下一個示例中,我們將了解如何操作實例。 由于該類是不可變的,因此每次操作都會導致一個新實例,而原始實例不受影響。

LocalDate date = LocalDate.of(2014, Month.JUNE, 10); date = date.withYear(2015); // 2015-06-10 date = date.plusMonths(2); // 2015-08-10 date = date.minusDays(1); // 2015-08-09

這些更改相對簡單,但是通常需要對日期進行更復雜的更改。 該java.time API包括一個機制來處理這一點- TemporalAdjuster。 時間調整器背后的想法是提供一種預包裝的實用程序,該實用程序能夠處理日期,例如獲取與該月的最后一天相對應的實例。 API中提供了常用的,但您可以添加自己的。 使用調節器非常簡單,但是可以從靜態導入中受益:

import static java.time.DayOfWeek.* import static java.time.temporal.TemporalAdjusters.* LocalDate date = LocalDate.of(2014, Month.JUNE, 10); date = date.with(lastDayOfMonth()); date = date.with(nextOrSame(WEDNESDAY));

看到正在使用調節器的立即React通常是對代碼與預期業務邏輯的接近程度的評價。 實現日期和時間業務邏輯非常重要。 我們要看的最后一件事是大量的日期手動操作。 如果您要在代碼庫中執行多次常規操作,請考慮編寫一次自己的調節器,并讓您的團隊將其作為預先編寫的,經過預先測試的組件來使用。

日期和時間為值

值得花點時間考慮一下是什么使LocalDate類成為一個值。 值是簡單的數據類型,其中兩個相等的實例完全可以替換-對象標識沒有實際含義。 String類是值的典范示例-我們通過equals()關心兩個字符串是否為真,而在==時我們不在乎它們是否相同

大多數日期和時間類也應該是值,并且java.time API滿足了這一期望。 因此,從來沒有充分的理由使用==比較兩個LocalDate實例,實際上Javadoc建議不要這樣做。

對于那些想了解更多信息的人,請參閱我最近對VALJO的定義,該定義為Java中的值對象定義了一組嚴格的規則,包括不可變性,工廠方法以及equals,hashCode,toStringcompareTo的良好定義。

備用日歷系統

java.time中的所有主要日期和時間類一樣, LocalDate類固定于單個日歷系統-ISO-8601標準中定義的日歷系統。

在ISO-8601日歷系統是事實上的世界歷法系統,也描述為proleptic公歷。 標準年為365天,leap年為366天。 年每4年發生一次,但不是每100年發生一次,除非可以被400整除。為進行一致的計算,第一年的前一年被視為零年。

使用此日歷系統作為默認日歷的第一個影響是日期不一定與GregorianCalendar的結果兼容。 在GregorianCalendar中 ,有來自割接儒略歷系統的陽歷其中15日發生在默認情況下1582年十月在該日期之前一個,儒略歷被使用,其中有一個閏年每4年沒有失敗。 在該日期之后,將使用公歷,它具有我們今天使用的更復雜的leap年系統。

鑒于日歷系統的這種變化是歷史事實,為什么新的java.time API不能對其建模? 原因是,今天大多數使用此類歷史日期的Java應用程序都是不正確的,因此繼續下去將是一個錯誤。 原因是,盡管羅馬的梵蒂岡城于1582年10月15日更改了日歷系統,但世界上大多數其他國家并沒有這樣做 。 特別是大英帝國,包括早期的美國,直到近200年后才于1752年9月14日改變。 俄羅斯直到1918年2月14日才改變,而瑞典的改變尤其混亂。 因此,事實上,1918年之前的日期的含義很容易被解釋,并且對格里高利日歷的一次轉換的信念是錯誤的。 因此,選擇LocalDate不具有切換功能是一個非常合理的選擇。 應用程序需要其他上下文信息,才能準確地解釋儒略歷和公歷之間的特定歷史日期。

在所有主要類別中都集中使用ISO-8601事實上的世界日歷系統的第二個影響是需要一組額外的類來處理其他日歷系統。 Chronology界面是備用日歷系統的主要入口點,允許您按語言環境名稱查找它們。 Java SE 8還提供了其他四個日歷系統-泰國佛教徒,Minguo,日語和Hirah。 其他日歷系統可以由應用程序提供。

每個日歷系統都有一個專用的日期類,因此有ThaiBuddhistDateMinguoDate,JapaneseDateHijrahDate 。 如果構建高度本地化的應用程序(例如日本政府的應用程序),則使用這些文件。 額外的接口ChronoLocalDate用作這四個接口的基本抽象,加上LocalDate,可在不知道其運行的日歷系統的情況下編寫代碼。 盡管存在這種抽象,但意圖是很少使用它。

理解為什么很少使用抽象對于正確使用整個java.time API 至關重要 。 事實是,當檢查當今的應用程序時,大多數嘗試以日歷系統中立方式運行的代碼都被破壞了。 例如,您不能假設一年中有12個月,而開發人員卻假設他們已經添加了整整一年就添加12個月。 您不能假設所有月份的長度大致相同-科普特日歷系統有12個月的30天和1個月的5或6天。 您也不能假設下一年的數字比當前年份大,因為日本皇帝改變時,日歷會像日本重新啟動年份一樣編號,通常是年中(您甚至不能假設同一天有兩天月份是同一年!)。

在日歷系統中立的方式下跨大型應用程序編寫代碼的唯一方法是進行繁瑣的代碼審查,其中要仔細檢查每一行日期和時間代碼,以免對ISO日歷系統產生偏見。 因此, java.time的推薦用法是在整個應用程序中使用LocalDate ,包括所有存儲,操縱和解釋業務規則。 唯一應使用ChronoLocalDate的時間是在本地化輸入或輸出時,通常是通過將用戶首選的日歷系統存儲在用戶配置文件中來實現的,即使那樣,大多數應用程序實際上并不需要該本地化級別。

有關此領域的完整原理,請參閱ChronoLocalDate的Javadoc 。

一天中的時間

超越日期,下一個要考慮的概念是Local-of-day,以LocalTime表示。 典型的例子可能是代表便利店的營業時間,例如從07:00到23:00(從早上7點到晚上11點)。 這樣的商店可能會在美國全境的那幾個小時營業,但當地時間忽略了時區。

LocalTime是一種沒有關聯的日期或時區的值類型。 當增加或減少時間量時,它將在午夜左右結束。 因此,20:00加6小時得出02:00。

使用LocalTime類似于使用LocalDate

LocalTime time = LocalTime.of(20, 30); int hour = date.getHour(); // 20 int minute = date.getMinute(); // 30 time = time.withSecond(6); // 20:30:06 time = time.plusMinutes(3); // 20:33:06

調整器機制也可以與LocalTime一起使用,但是調用它的時間的復雜處理較少。

合并日期和時間

下一個要考慮的類是LocalDateTime 。 此值類型是LocalDateLocalTime的簡單組合。 它代表沒有時區的日期和時間。

LocalDateTime可以直接創建,也可以通過組合日期和時間來創建:

LocalDateTime dt1 = LocalDateTime.of(2014, Month.JUNE, 10, 20, 30); LocalDateTime dt2 = LocalDateTime.of(date, time); LocalDateTime dt3 = date.atTime(20, 30); LocalDateTime dt4 = date.atTime(time);

第三個和第四個選項使用atTime() ,它提供了一種建立日期時間的流暢方法。 提供的大多數日期和時間類都具有“ at”方法,可以用這種方法將您擁有的對象與另一個對象結合起來以形成一個更復雜的對象。

LocalDateTime上的其他方法類似于LocalDateLocalTime的方法 。 這種熟悉的方法模式對于幫助學習API很有用。 下表總結了所使用的方法前綴:

字首

描述

從組成部分創建實例的靜態工廠方法。

嘗試從相似對象中提取實例的靜態工廠方法。 from()方法的類型安全性不如of()方法。

現在

在當前時間獲取實例的靜態工廠方法。

解析

靜態工廠方法,允許將字符串解析為對象的實例。

得到

獲取日期時間對象的部分狀態。

檢查日期時間對象是否為真。

返回日期時間對象的副本,其中部分狀態已更改。

返回添加了一定時間的日期時間對象的副本。

減去

返回減去時間量的日期時間對象的副本。

將此日期時間對象轉換為另一個,可以表示原始對象的部分或全部狀態。

將此日期時間對象與其他數據組合以創建更大或更復雜的日期時間對象。

格式

提供格式化該日期時間對象的功能。

瞬間

在處理日期和時間時,我們通常以年,月,日,小時,分鐘和秒為單位進行考慮。 但是,這只是時間的一種模式,我稱之為“人類”。 第二個通用模型是“機器”或“連續”時間。 在此模型中,時間軸上的一個點由單個大數字表示。 這種方法很容易讓計算機處理,并且從1970年的UNIX秒計數中可以看出,與Java中的1970年的毫秒計數相匹配。

java.time API通過Instant值類型提供時間的機器視圖。 它提供了在沒有任何其他上下文信息(例如時區)的情況下表示時間線上的點的功能。 從概念上講,它僅表示自1970年(UTC 1970年1月1日開始的午夜)以來的秒數。 由于API基于納秒,因此Instant類提供了將精度存儲到納秒的能力。

Instant start = Instant.now(); // perform some calculation Instant end = Instant.now(); assert end.isAfter(start);

Instant類通常用于存儲和比較時間戳,您需要在其中記錄事件發生的時間,而無需記錄有關事件發生的時區的任何信息。

在許多方面,Instant有趣的方面是您無法使用它,而不是您可以做什么。 例如,這些代碼行將引發異常:

instant.get(ChronoField.MONTH_OF_YEAR); instant.plus(6, ChronoUnit.YEARS);

它們會引發異常,因為Instant僅包含數秒和十億分之一秒的時間,并且無法處理對人類有意義的單位。 如果需要此功能,則需要提供時區信息。

時區

英國引入了時區的概念, 當時鐵路的發明以及通信方面的其他改進使人們突然可以覆蓋遠處,因為太陽時間的變化很重要。 直到那時,每個村莊和城鎮都有自己的基于太陽的時間定義,通常以日d為基準。

最初在英國布里斯托(Bristol)交易所大樓上的時鐘照片顯示了這種混淆的一個例子。 紅手顯示格林威治標準時間,黑手顯示布里斯托爾時間,相差10分鐘:

在技??術的推動下,標準時區系統得到了發展,取代了較早的當地太陽時。 但是關鍵事實是時區是政治創造。 它們通常用于展示對該地區的政治控制,例如克里米亞到莫斯科時期的最新變化。 與任何政治事物一樣,相關規則經常違反邏輯。 規則可以而且確實會在很少通知的情況下進行更改。

時區規則由發布IANA時區數據庫的國際組織收集和收集。 這組數據包含地球上每個區域的標識符以及該區域時區變化的歷史。 標識符的格式為“歐洲/倫敦”或“美國/紐約”。

java.time API之前,您使用TimeZone類來表示時區。 現在,您使用ZoneId類。 有兩個主要區別。 首先, ZoneId是不可變的,它提供了將實例存儲在靜態變量中的功能。 其次,實際規則本身在ZoneRules舉行,而不是在本身了zoneid,只需撥打了zoneid getRules()獲得的規則。

時區的一種常見情況是與UTC /格林威治時間的固定偏移量。 在談論時差時,通常會遇到這種情況,例如紐約比倫敦落后5小時。 ZoneOffset類是ZoneId的子類, 代表倫敦格林威治的零子午線的時間偏移。

作為開發人員,最好不必處理時區及其復雜性。 java.time API允許您盡可能地做到這一點。 盡可能使用LocalDateLocalTimeLocalDateTimeInstant類。 當您無法避免時區時, ZonedDateTime類將處理該要求。

ZonedDateTime類管理從人類時間線(在桌面日歷和掛鐘上看到)到機器時間線(以秒為單位)的轉換。 這樣,您可以從本地類或即時實例創建ZonedDateTime:

ZoneId zone = ZoneId.of("Europe/Paris"); LocalDate date = LocalDate.of(2014, Month.JUNE, 10); ZonedDateTime zdt1 = date.atStartOfDay(zone); Instant instant = Instant.now(); ZonedDateTime zdt2 = instant.atZone(zone);

時區最煩人的部分之一是夏令時(DST)。 使用DST,與格林威治的偏移量每年更改兩次(或多次),通常在Spring前進,在秋季/秋季前進。 進行這些調整后,我們所有人都必須更改房屋周圍點綴的掛鐘。 這些更改由java.time稱為偏移量轉換 。 在Spring,本地時間軸上存在一個“間隙”,其中一些本地時間不會發生。 相比之下,在秋天/秋天,當某些本地時間出現兩次時會出現“重疊”。

ZonedDateTime類使用其工廠方法和操作方法進行處理。 例如,添加一天將添加一個邏輯日,如果超過了DST邊界,則可能會大于或小于24小時。 同樣,方法atStartOfDay()之所以如此命名,是因為您不能假設結果時間將是午夜-從午夜到凌晨1點可能存在DST間隙。

關于DST的最后一個技巧。 如果您想證明您已經考慮過DST重疊(同一本地時間發生兩次)應該發生什么,則可以使用專用于處理重疊的兩種特殊方法之一:

zdt = zdt.withEarlierOffsetAtOverlap(); zdt = zdt.withLaterOffsetAtOverlap();

如果對象與DST重疊,則使用這兩種方法之一將選擇較早或較晚的時間。 在所有其他情況下,這些方法將無效。

時間量

到目前為止討論的日期和時間類別以各種方式代表了時間軸上的點。 為時間量提供了兩個附加值類型。

Duration類表示以秒和納秒為單位的時間量。 例如,“ 23.6秒”。

Period類代表以年,月和日為單位的時間量。 例如,“ 3年2個月零6天”。

這些可以添加到主要日期和時間類別中,也可以從其中刪除:

Period sixMonths = Period.ofMonths(6); LocalDate date = LocalDate.now(); LocalDate future = date.plus(sixMonths);

格式化和解析

整個軟件包專用于格式化和打印日期和時間-java.time.format 。 該軟件包圍繞DateTimeFormatter及其關聯的生成器DateTimeFormatterBuilder展開

創建格式化程序的最常見方法是DateTimeFormatter上的靜態方法和常量。 這些包括:

  • 通用 ISO格式的常量,例如ISO_LOCAL_DATE
  • 模式字母,例如ofPattern(“ dd / MM / uuuu” )。
  • 本地化的樣式,例如ofLocalizedDate(FormatStyle.MEDIUM )。

擁有格式化程序后,通常可以通過將其傳遞給主要日期和時間類的相關方法來使用它:

DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/uuuu"); LocalDate date = LocalDate.parse("24/06/2014", f); String str = date.format(f);

這樣,您就可以與格式化程序本身上的format和parse方法隔離。

如果需要控制格式化的語言環境,請在格式化程序上使用withLocale(Locale)方法。 類似的方法可以控制日歷系統,時區,十進制編號系統和解析的分辨率。

如果需要更多控制,請參見DateTimeFormatterBuilder類,該類允許逐步建立復雜的格式。 它還具有格式化程序不區分大小寫的解析,寬松的解析,填充和可選部分的功能。

摘要

java.time API是Java SE 8中用于日期和時間的新的全面模型。它將在Joda-Time中開始的想法和實現提高到一個新的水平,并最終允許開發人員將java.util.DateCalendar留在后面。 絕對可以再次享受日期和時間編程的時間!

  • Oracle 官方教程
  • 非官方項目主頁
  • ThreeTen-Extra項目 ,帶有補充核心Java SE的其他類

翻譯自: https://www.infoq.com/articles/java.time?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

團隊和做的直觀圖

總結

以上是生活随笔為你收集整理的团队和做的直观图_直观,可靠的日期和时间处理,终于出现在Java中的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。