Java 8 Time Zone和Offset类使用示例

x33g5p2x  于2021-08-22 转载在 Java  
字(5.4k)|赞(0)|评价(0)|浏览(305)

在本指南中,我们将结合实例讨论Java 8的Time ZoneOffset类。
时区是地球上使用相同标准时间的区域。每个时区都由一个标识符描述,通常具有区域/城市(亚洲/东京)的格式,以及与格林威治/UTC时间的偏移。例如,东京的偏移量是+09:00。
该指南的例子可在Github上找到。
Date-Time API提供了两个用于指定时区或偏移量的类。

  • ZoneId 

  • ZoneOffset
    日期-时间API提供了三个基于时间的类,用于处理时区。

  • ZonedDateTime

  • OffsetDateTime

  • OffsetTime
    让我们用例子来讨论每个类。

1. ZoneId and ZoneOffset

Date-Time API 提供了两个类来指定一个时区或一个偏移。

  • ZoneId - 指定一个时区标识符,并提供在即时和LocalDateTime之间的转换规则。

  • ZoneOffset - 指定从格林威治/UTC时间的时区偏移。

1.1 ZoneId和ZoneOffset类示例

下面的代码来自TimeZoneId类的例子,它打印了所有使用与格林威治/UTC的偏移量的时区列表,这些时区不是以整小时定义的。

例子。演示ZoneId和ZoneOffset类的程序。 

package com.ramesh.java8.datetime;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

public class TimeZoneId {
 public static void main(String[] args) {

  // Get the set of all time zone IDs.
  Set<String> allZones = ZoneId.getAvailableZoneIds();

  // Create a List using the set of zones and sort it.
  List<String> zoneList = new ArrayList<String>(allZones);
  Collections.sort(zoneList);

  LocalDateTime dt = LocalDateTime.now();

  Path p = Paths.get("timeZones");
  try (BufferedWriter tzfile = Files.newBufferedWriter(p, StandardCharsets.US_ASCII)) {
   for (String s : zoneList) {
    ZoneId zone = ZoneId.of(s);
    ZonedDateTime zdt = dt.atZone(zone);
    ZoneOffset offset = zdt.getOffset();
    int secondsOfHour = offset.getTotalSeconds() % (60 * 60);
    String out = String.format("%35s %10s%n", zone, offset);

    // Write only time zones that do not have a whole hour offset
    // to standard out.
    if (secondsOfHour != 0) {
     System.out.printf(out);
    }

    // Write all time zones to the file.
    tzfile.write(out);
   }
  } catch (IOException x) {
   System.err.format("IOException: %s%n", x);
  }
 }
}

输出。

America/St_Johns     -02:30
                      Asia/Calcutta     +05:30
                       Asia/Colombo     +05:30
                         Asia/Kabul     +04:30
                     Asia/Kathmandu     +05:45
                      Asia/Katmandu     +05:45
                       Asia/Kolkata     +05:30
                     Asia/Pyongyang     +08:30
                       Asia/Rangoon     +06:30
                        Asia/Tehran     +04:30
                        Asia/Yangon     +06:30
                 Australia/Adelaide     +09:30
              Australia/Broken_Hill     +09:30
                   Australia/Darwin     +09:30
                    Australia/Eucla     +08:45
                      Australia/LHI     +10:30
                Australia/Lord_Howe     +10:30
                    Australia/North     +09:30
                    Australia/South     +09:30
               Australia/Yancowinna     +09:30
                Canada/Newfoundland     -02:30
                       Indian/Cocos     +06:30
                               Iran     +04:30
                            NZ-CHAT     +12:45
                    Pacific/Chatham     +12:45
                  Pacific/Marquesas     -09:30

Date-Time API 提供了三个基于时间的类,用于处理时区。

  • ZonedDateTime - 处理具有相应时区的日期和时间,其时区偏移量为格林威治/UTC。 

  • OffsetDateTime - 处理一个日期和时间,其对应的时区与格林威治/北卡罗来纳州的时区偏移,没有时区ID。 

  • OffsetTime - 处理与格林威治/北卡罗来纳州相应的时区偏移的时间,没有时区标识。
    让我们通过一个例子来详细讨论这些类。

2. ZonedDateTime

  • ZonedDateTime类结合了LocalDateTime类和ZoneId类。 

  • 它用来表示一个完整的日期(年、月、日)和时间(时、分、秒、纳秒),并带有一个时区(地区/城市,如欧洲/巴黎)。

2.1 ZonedDateTime类示例

下面的代码来自于Flight的例子,将从旧金山到东京的航班的起飞时间定义为ZonedDateTimeAmerica/Los Angeles时区。 

withZoneSameInstantplusMinutes方法被用来创建一个ZonedDateTime的实例,代表650分钟飞行后到达东京的预计时间。ZoneRulesisDaylightSavings方法决定了航班到达东京时是否是夏令时。

package com.ramesh.java8.datetime;

import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
//*
/* This example uses ZonedDateTime to calculate the arrival time of
/* a flight that leaves from San Francisco and arrives in Tokyo.
/* The flight is 10 hours, 50 minutes long. Formatters are used to
/* print the departure and arrival times.
/*/

public class FlightZoneDateTimeExample {
    public static void main(String[] args) {
        DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM d yyyy  hh:mm a");

        // Leaving from San Francisco on July 20, 2013, at 7:30 p.m.
        LocalDateTime leaving = LocalDateTime.of(2013, Month.JULY, 20, 19, 30);
        ZoneId leavingZone = ZoneId.of("America/Los_Angeles"); 
        ZonedDateTime departure = ZonedDateTime.of(leaving, leavingZone);

        try {
            String out1 = departure.format(format);
            System.out.printf("LEAVING:  %s (%s)%n", out1, leavingZone);
        } catch (DateTimeException exc) {
            System.out.printf("%s can't be formatted!%n", departure);
            throw exc;
        }

        // Flight is 10 hours and 50 minutes, or 650 minutes
        ZoneId arrivingZone = ZoneId.of("Asia/Tokyo"); 
        ZonedDateTime arrival = departure.withZoneSameInstant(arrivingZone)
                                         .plusMinutes(650);

        try {
            String out2 = arrival.format(format);
            System.out.printf("ARRIVING: %s (%s)%n", out2, arrivingZone);
        } catch (DateTimeException exc) {
            System.out.printf("%s can't be formatted!%n", arrival);
            throw exc;
        }

        if (arrivingZone.getRules().isDaylightSavings(arrival.toInstant())) 
            System.out.printf("  (%s daylight saving time will be in effect.)%n",
                              arrivingZone);
        else
            System.out.printf("  (%s standard time will be in effect.)%n",
                              arrivingZone);
    }
}

输出。

LEAVING:  Jul 20 2013  07:30 PM (America/Los_Angeles)
ARRIVING: Jul 21 2013  10:20 PM (Asia/Tokyo)
(Asia/Tokyo standard time will be in effect.)

3. OffsetDateTime

  • OffsetDateTime类,实际上是将LocalDateTime类与ZoneOffset类结合起来。 

  • 它用来表示一个完整的日期(年、月、日)和时间(时、分、秒、纳秒),并与格林威治/UTC时间有一个偏移(+/-小时:分钟,如+06:00或-08:00)。

3.1 OffsetDateTime类示例

下面的例子使用OffsetDateTimeTemporalAdjuster.lastDay方法来查找2013年7月的最后一个星期四。

// Find the last Thursday in July 2013.
LocalDateTime localDate = LocalDateTime.of(2013, Month.JULY, 20, 19, 30);
ZoneOffset offset = ZoneOffset.of("-08:00");

OffsetDateTime offsetDate = OffsetDateTime.of(localDate, offset);
OffsetDateTime lastThursday =
        offsetDate.with(TemporalAdjusters.lastInMonth(DayOfWeek.THURSDAY));
System.out.printf("The last Thursday in July 2013 is the %sth.%n",
                   lastThursday.getDayOfMonth());

输出。

The last Thursday in July 2013 is the 25th.

4. OffsetTime

  • OffsetTime类,实际上是将LocalTime类和ZoneOffset类结合起来。

  • 它用于表示时间(时、分、秒、纳秒),与格林威治/UTC时间有一个偏移(+/-小时:分钟,如+06:00或-08:00)。

  • OffsetTime类用于与OffsetDateTime类相同的情况,但不需要跟踪日期时。

相关文章