<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 新的日期 API ## 簡介 Java 8中的時區操作被很大程度上簡化了,新的時區類`java.time.ZoneId`是原有的`java.util.TimeZone`類的替代品。 ZoneId對象可以通過`ZoneId.of()`方法創建,也可以通過`ZoneId.systemDefault()`獲取系統默認時區: ~~~ ZoneId shanghaiZoneId = ZoneId.of("Asia/Shanghai"); ZoneId systemZoneId = ZoneId.systemDefault(); ~~~ `of()`方法接收一個“區域/城市”的字符串作為參數,你可以通過`getAvailableZoneIds()`方法獲取所有合法的“區域/城市”字符串: ~~~ Set<String> zoneIds = ZoneId.getAvailableZoneIds(); ~~~ 對于老的時區類`TimeZone`,Java 8也提供了轉化方法: ~~~ ZoneId oldToNewZoneId = TimeZone.getDefault().toZoneId(); ~~~ 有了`ZoneId`,我們就可以將一個`LocalDate`、`LocalTime`或`LocalDateTime`對象轉化為`ZonedDateTime`對象: ~~~ LocalDateTime localDateTime = LocalDateTime.now(); ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, shanghaiZoneId); ~~~ `ZonedDateTime`對象由兩部分構成,`LocalDateTime`和`ZoneId`,其中`2018-03-03T15:26:56.147`部分為`LocalDateTime`,`+08:00[Asia/Shanghai]`部分為ZoneId。 另一種表示時區的方式是使用`ZoneOffset`,它是以當前時間和**世界標準時間(UTC)/格林威治時間(GMT)**的偏差來計算,例如: ~~~ ZoneOffset zoneOffset = ZoneOffset.of("+09:00"); LocalDateTime localDateTime = LocalDateTime.now(); OffsetDateTime offsetDateTime = OffsetDateTime.of(localDateTime, zoneOffset); ~~~ ## Instant Instant類在Java日期與時間功能中,表示了時間線上一個確切的點,定義為距離初始時間的時間差(初始時間為GMT 1970年1月1日00:00)經測量一天有86400秒,從初始時間開始不斷向前移動。 **創建一個Instant實例** 你可以通過Instant類的工廠方法創建一個Instant實例,例如你可以調用instant.now()來創建一個確切的表達當前時間的Instant對象: ~~~ Instant now = Instant.now(); ~~~ 另外也有一些其它方法能創建Instant,具體請查閱Java官方文檔。 **訪問Instant的時間** 一個Instant對象里有兩個域:距離初始時間的秒鐘數、在當前一秒內的第幾納秒,他們的組合表達了當前時間點。你可以通過以下兩個方法得到它們的值: ~~~ long seconds = getEpochSecond() int nanos = getNano() ~~~ **Instant的計算** Instant類有一些方法,可以用于獲得另一Instant的值,例如: * `plusSeconds()` * `plusMillis()` * `plusNanos()` * `minusSeconds()` * `minusMillis()` * `minusNanos()` 我下面將向你展示兩個例子,來說明這些方法如何使用: ~~~ Instant now = Instant.now(); Instant later = now.plusSeconds(3); Instant earlier = now.minusSeconds(3); ~~~ 第一行獲得了一個Instant對象,表示當前時間。第二行創建了一個Instant表示三秒后,第三行創建了一個Instant表示三秒前。 > seconds 表示從`1970-01-01 00:00:00`開始到現在的秒數,nanos 表示納秒部分(nanos的值不會超過999,999,999) ## Clock Clock類提供了訪問當前日期和時間的方法,Clock是時區敏感的,可以用來取代`System.currentTimeMillis()`來獲取當前的微秒數。 某一個特定的時間點也可以使用Instant類來表示,Instant 類也可以用來創建老的`java.util.Date`對象。 ~~~ Clock clock = Clock.systemDefaultZone(); long millis = clock.millis(); Instant instant = clock.instant(); Date legacyDate = Date.from(instant); // legacy java.util.Date ~~~ ## LocalDate LocalDate類是Java 8中日期時間功能里表示一個本地日期的類,它的日期是無時區屬性的。 可以用來表示生日、節假日期等等。這個類用于表示一個確切的日期,而不是這個日期所在的時間(如java.util.Date中的2000.01.01表示的實際是這一天的00:00這個瞬間)。 LocalDate類位于java.time包下,人名叫java.time.LocalDate,創建出來的實例也是不可變對象,所以涉及它的計算方法將返回一個新的LocalDate。 **創建一個LocalDate實例** 我們有多種方式可以創建出`LocalDate`實例。第一種方法是使用`now()`方法獲得值為今天當日的`LocalDate`對象: ~~~ LocalDate localDate = LocalDate.now(); ~~~ 另一種方法是使用年月日信息構造出LocalDate對象: ~~~ LocalDate localDate2 = LocalDate.of(2018, 3, 3); ~~~ LocalDate 的`of()`方法創建出一個指定年月日的日期,并且沒有時區信息。 **訪問日期信息** 可以用如下方法訪問LocalDate中的日期信息: ~~~ int year = localDate.getYear(); Month month = localDate.getMonth(); int dayOfMonth = localDate.getDayOfMonth(); int dayOfYear = localDate.getDayOfYear(); DayOfWeek dayOfWeek = localDate.getDayOfWeek(); ~~~ 可以注意到getMonth()與getDayOfWeek()方法返回了一個枚舉類型代替一個int。你可以通過枚舉類型中的getValue()來獲得信息。 **LocalDate計算** 你可以進行一堆簡單的日期計算,只要使用如下的方法: * `plusDays()` * `plusWeeks()` * `plusMonths()` * `plusYears()` * `minusDays()` * `minusWeeks()` * `minusMonths()` * `minusYears()` 以下舉幾個使用的例子來幫助理解使用: ~~~ LocalDate d = LocalDate.of(2018, 3, 5); LocalDate d1 = localDate.plusYears(3); LocalDate d2 = localDate.minusYears(3); ~~~ 1. 第一行創建出一個新的LocalDate對象d,表示2018.3.5。 2. 第二行創建了值等于d日期3年后的LocalDate對象,第三行也是一樣,只是值改為d日期的三年前。 ## LocalTime LocalTime類是Java 8中日期時間功能里表示一整天中某個時間點的類,它的時間是無時區屬性的(早上10點等等)。比如你需要描述學校幾點開學,這個時間不涉及在什么城市,這個描述是對任何國家城市都適用的,此時使用無時區的LocalTime就足夠了。 LocalTime類的對象也是不可變的,所以計算方法會返回一個新的LocalTime實例。 **創建一個LocatTime實例** 有多種方式可以新建LocalTime實例。比如使用當前時間作為值新建對象: ~~~ LocalTime localTime = LocalTime.now(); ~~~ 另一種方式是使用指定的時分秒和納秒來新建對象: ~~~ LocalTime localTime2 = LocalTime.of(21, 30, 59, 11001); ~~~ 也有另一種版本的`of()`方法只需要小時分鐘兩項,或時分秒三項值作為參數。 **訪問LocalTime對象的時間** 你可以通過這些方法訪問其時、分、秒、納秒: * `getHour()` * `getMinute()` * `getSecond()` * `getNano()` **LocalTime的計算** LocalTime類包含一系列方法,能幫你完成時間計算: * `plusHours()` * `plusMinutes()` * `plusSeconds()` * `plusNanos()` * `minusHours()` * `minusMinutes()` * `minusSeconds()` * `minusNanos()` 以下舉一個例子: ~~~ LocalTime localTime2 = LocalTime.of(21, 30, 59, 11001); LocalTime localTimeLater = localTime.plusHours(3); LocalTime localTimeEarlier = localTime.minusHours(3); ~~~ 1. 第一行新建一個LocalTime實例,表示21:30:50的第11001納秒。 2. 第二行新建了一個LocalTime實例表示這個時間的三小時后,第三行表示三小時前。 3. LocalTime類是Java 8中日期時間功能里表示一整天中某個時間點的類,它的時間是無時區屬性的(早上10點等等)。比如你需要描述學校幾點開學,這個時間不涉及在什么城市,這個描述是對任何國家城市都適用的,此時使用無時區的LocalTime就足夠了。 LocalTime類的對象也是不可變的,所以計算方法會返回一個新的LocalTime實例。 ## LocalDateTime LocalDateTime類是Java 8中日期時間功能里,用于表示當地的日期與時間的類,它的值是無時區屬性的。你可以將其視為Java 8中LocalDate與LocalTime兩個類的結合。 LocalDateTime類的值是不可變的,所以其計算方法會返回一個新的LocalDateTime實例。 **創建一個LocatDateTime實例** 可以通過LocalDateTime的靜態工廠方法來創建LocalDateTime實例。以下舉例使用`now()`方法創建: ~~~ LocalDateTime localDateTime = LocalDateTime.now(); ~~~ 另一種方式是使用指定的年月日、時分秒、納秒來新建對象: ~~~ LocalDateTime localDateTime2 = LocalDateTime.of(2018, 11, 26, 13, 55, 36, 123); ~~~ **訪問LocalDateTime對象的時間** 你可以通過這些方法訪問其日期時間: * `getYear()` * `getMonth()` * `getDayOfMonth()` * `getDayOfWeek()` * `getDayOfYear()` * `getHour()` * `getMinute()` * `getSecond()` * `getNano()` 這些方法中有一些返回int有一些返回枚舉類型,你可以通過枚舉類型中的`getValue()`方法來獲得int值。 **LocalDateTime的計算** LocalDateTime 類包含一系列方法,能幫你完成時間計算: * `plusYears()` * `plusMonths()` * `plusDays()` * `plusHours()` * `plusMinutes()` * `plusSeconds()` * `plusNanos()` * `minusYears()` * `minusMonths()` * `minusDays()` * `minusHours()` * `minusMinutes()` * `minusSeconds()` * `minusNanos()` 以下舉一個例子: ~~~ LocalDateTime localDateTime = LocalDateTime.now(); LocalDateTime localDateTime1 = localDateTime.plusYears(3); LocalDateTime localDateTime2 = localDateTime.minusYears(3); ~~~ 1. 第一行新建一個LocalDateTime實例表示當前這個時間。 2. 第二行新建了一個LocalDateTime實例表示三年后。 3. 第三行也新建了一個LocalDateTime實例表示三小時前。 ## ZonedDateTime ZonedDateTime類是Java 8中日期時間功能里,用于表示帶時區的日期與時間信息的類。可以用于表示一個真實事件的開始時間,如某火箭升空時間等等。 ZonedDateTime 類的值是不可變的,所以其計算方法會返回一個新的ZonedDateTime 實例。 **創建一個ZonedDateTime實例** 有多種方式可以新建ZonedDateTime實例。比如使用當前時間作為值新建對象: ~~~ ZonedDateTime dateTime = ZonedDateTime.now(); ~~~ 另一種方式是使用指定的年月日、時分秒、納秒以及時區ID來新建對象: ~~~ ZoneId zoneId = ZoneId.of("UTC+1"); ZonedDateTime dateTime2 = ZonedDateTime.of(2015, 11, 30, 23, 45, 59, 1234, zoneId); ~~~ **訪問ZonedDateTime對象的時間** 你可以通過這些方法訪問其日期時間: * `getYear()` * `getMonth()` * `getDayOfMonth()` * `getDayOfWeek()` * `getDayOfYear()` * `getHour()` * `getMinute()` * `getSecond()` * `getNano()` 這些方法中有一些返回int有一些返回枚舉類型,但可以通過枚舉類型中的getValue()方法來獲得int值。 **ZonedDateTime的計算** ZonedDateTime類包含一系列方法,能幫你完成時間計算: * `plusYears()` * `plusMonths()` * `plusDays()` * `plusHours()` * `plusMinutes()` * `plusSeconds()` * `plusNanos()` * `minusYears()` * `minusMonths()` * `minusDays()` * `minusHours()` * `minusMinutes()` * `minusSeconds()` * `minusNanos()` 但注意計算時,若不巧跨越了夏令時(會補一小時或減一小時),可能得不到希望的結果。一個替代的正確做法是使用Period: ~~~ ZonedDateTime zoneDateTime = previousDateTime.plus(Period.ofDays(3)); ~~~ **時區** 時區是用ZoneId類表示的,你可以使用ZoneId.now()或ZoneId.of(“xxx”)來實例化: ~~~ ZoneId zoneId = ZoneId.of("UTC+1"); ~~~ 傳給`of()`方法的參數是時區的ID,如“UTC+1”指距離UTC(格林威治時間)有一小時的時差,你可以使用你想要的時差來表示ZoneId(如+1與-5等等) 你也可以使用另一種方式表示zone id,即使用地區名字,也是可以的: ~~~ ZoneId zoneId2 = ZoneId.of("Europe/Copenhagen"); ZoneId zoneId3 = ZoneId.of("Europe/Paris"); ~~~ ## DateTimeFormatter DateTimeFormatter類是Java 8中日期時間功能里,用于解析和格式化日期時間的類,位于`java.time.format`包下。 **預定義的DateTimeFormatter實例** DateTimeFormatter類包含一系列預定義(常量)的實例,可以解析和格式化一些標準時間格式。這將讓你免除麻煩的時間格式定義,類中包含如下預定義的實例: ~~~ BASIC_ISO_DATE ISO_LOCAL_DATE ISO_LOCAL_TIME ISO_LOCAL_DATE_TIME ISO_OFFSET_DATE ISO_OFFSET_TIME ISO_OFFSET_DATE_TIME ISO_ZONED_DATE_TIME ISO_INSTANT ISO_DATE ISO_TIME ISO_DATE_TIME ISO_ORDINAL_TIME ISO_WEEK_DATE RFC_1123_DATE_TIME ~~~ 每個預定義的DateTimeFormatter實例都有不同的日期格式,我就不解釋全部的了。具體的可以查閱Java官方文檔,但我在這篇的后續中會解釋其中幾個,以方便理解。 **格式化日期** 當你獲取一個DateTimeFormatter實例后,就可以用format()方便來將一個日期格式化為某種字符串,例如: ~~~ DateTimeFormatter formatter = DateTimeFormatter.BASIC_ISO_DATE; String formattedDate = formatter.format(LocalDate.now()); System.out.println(formattedDate); ~~~ 這個樣例把LocalDate對象格式化了,并輸出20150703,這個輸出表示現在2018年,3月5日。 再舉一個關于ZonedDateTime的例子: ~~~ DateTimeFormatter formatter = DateTimeFormatter.BASIC_ISO_DATE; String formattedZonedDate = formatter.format(ZonedDateTime.now()); System.out.println("formattedZonedDate = " + formattedZonedDate); ~~~ 這個例子會輸出:20180305+0800 表示今年2018年,3月5日,位于UTC+8時區。 ## Duration 一個Duration對象表示兩個Instant間的一段時間,是在Java 8中加入的新功能。 一個Duration實例是不可變的,當創建出對象后就不能改變它的值了。你只能通過Duration的計算方法,來創建出一個新的Durtaion對象。你會在之后的教程中見到的。 **創建Duration實例** 使用`Duration`類的工廠方法來創建一個`Duration`對象,以下是一個使用`between()`的例子: ~~~ Instant first = Instant.now(); // wait some time while something happens Instant second = Instant.now(); Duration duration = Duration.between(first, second); ~~~ **訪問Duration的時間** 一個Duration對象里有兩個域:納秒值(小于一秒的部分),秒鐘值(一共有幾秒),他們的組合表達了時間長度。注意屯使用System.getCurrentTimeMillis()時不同,Duration不包含毫秒這個屬性。 你可以通過以下兩個方法得到它們的值: ~~~ long seconds = getSeconds() int nanos = getNano() ~~~ 你也可以轉換整個時間到其它單位如納秒、分鐘、小時、天: * `toNanos()` * `toMillis()` * `toMinutes()` * `toHours()` * `toDays()` 舉例而言:`toNanos()`與`getNano()`不同,`toNanos()`獲得的是`Duration`整個時間共有多少納秒, 而`getNano()`只是獲得這段時間中小于一秒的部分。 你也許會問,為什么沒有`toSeconds()`方法,因為已經有`getSeconds()`這個方法能達到同樣的功能了。 **Duration計算** Duration類包含一系列的計算方法: * `plusNanos()` * `plusMillis()` * `plusSeconds()` * `plusMinutes()` * `plusHours()` * `plusDays()` * `minusNanos()` * `minusMillis()` * `minusSeconds()` * `minusMinutes()` * `minusHours()` * `minusDays()` 這些方法所做的事都是相似的,我在這兒也不展示內部實現細節了,就展示一個加減的例子吧: ~~~ Duration start = ... //obtain a start duration Duration added = start.plusDays(3); Duration subtracted = start.minusDays(3); ~~~ 1. 第一行創建了一個Duration對象叫start,具體怎么創建可以參考前面的代碼。 2. 第二三行樣例創建了兩個新的Duration,通過調用start的加減操作,使得added對象表示的時間比start多三天,而substracted則少三天。 所有的計算方法都會返回一個新的Duration,以保證Duration的不可變屬性。 ~~~ long days = duration.toDays(); // 這段時間的總天數 long hours = duration.toHours(); // 這段時間的小時數 long minutes = duration.toMinutes(); // 這段時間的分鐘數 long seconds = duration.getSeconds(); // 這段時間的秒數 long milliSeconds = duration.toMillis(); // 這段時間的毫秒數 long nanoSeconds = duration.toNanos(); // 這段時間的納秒數 ~~~ ## 其他操作 ### 增加和減少日期 Java 8中的日期/時間類都是不可變的,這是為了保證線程安全。當然,新的日期/時間類也提供了方法用于創建對象的可變版本,比如增加一天或者減少一天: ~~~ LocalDate date = LocalDate.of(2017, 1, 5); // 2017-01-05 LocalDate date1 = date.withYear(2016); // 修改為 2016-01-05 LocalDate date2 = date.withMonth(2); // 修改為 2017-02-05 LocalDate date3 = date.withDayOfMonth(1); // 修改為 2017-01-01 LocalDate date4 = date.plusYears(1); // 增加一年 2018-01-05 LocalDate date5 = date.minusMonths(2); // 減少兩個月 2016-11-05 LocalDate date6 = date.plus(5, ChronoUnit.DAYS); // 增加5天 2017-01-10 ~~~ 上面例子中對于日期的操作比較簡單,但是有些時候我們要面臨更復雜的時間操作,比如將時間調到下一個工作日, 或者是下個月的最后一天,這時候我們可以使用`with()`方法的另一個重載方法,它接收一個TemporalAdjuster參數, 可以使我們更加靈活的調整日期: ~~~ LocalDate date7 = date.with(nextOrSame(DayOfWeek.SUNDAY)); // 返回下一個距離當前時間最近的星期日 LocalDate date9 = date.with(lastInMonth(DayOfWeek.SATURDAY)); // 返回本月最后一個星期六 ~~~ 要使上面的代碼正確編譯,你需要使用靜態導入`TemporalAdjusters`對象: `import static java.time.temporal.TemporalAdjusters.*;` `TemporalAdjusters`類中包含了很多靜態方法可以直接使用,下面的表格列出了一些方法: ![](https://img.kancloud.cn/6b/27/6b271cd0d99033308867025c0f6a56d7_948x486.png) 如果上面表格中列出的方法不能滿足你的需求,你還可以創建自定義的`TemporalAdjuster`接口的實現, `TemporalAdjuster`也是一個函數式接口,所以我們可以使用Lambda表達式: ~~~ @FunctionalInterface public interface TemporalAdjuster { Temporal adjustInto(Temporal temporal); } ~~~ 比如給定一個日期,計算該日期的下一個工作日(不包括星期六和星期天): ~~~ LocalDate date = LocalDate.of(2017, 1, 5); date.with(temporal -> { // 當前日期 DayOfWeek dayOfWeek = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK)); // 正常情況下,每次增加一天 int dayToAdd = 1; // 如果是星期五,增加三天 if (dayOfWeek == DayOfWeek.FRIDAY) { dayToAdd = 3; } // 如果是星期六,增加兩天 if (dayOfWeek == DayOfWeek.SATURDAY) { dayToAdd = 2; } return temporal.plus(dayToAdd, ChronoUnit.DAYS); }); ~~~ ### 其他歷法 Java中使用的歷法是ISO 8601日歷系統,它是世界民用歷法,也就是我們所說的公歷。平年有365天,閏年是366天。閏年的定義是:非世紀年,能被4整除;世紀年能被400整除。為了計算的一致性,公元1年的前一年被當做公元0年,以此類推。 此外Java 8還提供了4套其他歷法(很奇怪為什么沒有漢族人使用的農歷),每套歷法都包含一個日期類,分別是: * `ThaiBuddhistDate`:泰國佛教歷 * `MinguoDate`:中華民國歷 * `JapaneseDate`:日本歷 * `HijrahDate`:伊斯蘭歷 每個日期類都繼承`ChronoLocalDate`類,所以可以在不知道具體歷法的情況下也可以操作。不過這些歷法一般不常用,除非是有某些特殊需求情況下才會使用。 這些不同的歷法也可以用于向公歷轉換: ~~~ LocalDate date = LocalDate.now(); JapaneseDate jpDate = JapaneseDate.from(date); ~~~ 由于它們都繼承ChronoLocalDate類,所以在不知道具體歷法情況下,可以通過ChronoLocalDate類操作日期: ~~~ Chronology jpChronology = Chronology.ofLocale(Locale.JAPANESE); ChronoLocalDate jpChronoLocalDate = jpChronology.dateNow(); ~~~ 我們在開發過程中應該盡量避免使用`ChronoLocalDate`,盡量用與歷法無關的方式操作時間,因為不同的歷法計算日期的方式不一樣, 比如開發者會在程序中做一些假設,假設一年中有12個月,如果是中國農歷中包含了閏月,一年有可能是13個月, 但開發者認為是12個月,多出來的一個月屬于明年的。 再比如假設年份是累加的,過了一年就在原來的年份上加一,但日本天皇在換代之后需要重新紀年,所以過了一年年份可能會從1開始計算。 在實際開發過程中建議使用`LocalDate`,包括存儲、操作、業務規則的解讀;除非需要將程序的輸入或者輸出本地化, 這時可以使用`ChronoLocalDate`類。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看