簡體   English   中英

如何在特定時區獲取日期?

[英]How to get date in a specific timezone?

大家好 我正在使用以下方法獲取 GMT 時區的當前時間

public static Timestamp getCurrentTimeGMT() {

        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        long time = c.getTimeInMillis();
        long offset = TimeZone.getDefault().getOffset(time);
        return new Timestamp(time - offset);

    }

但是當我嘗試使用相同的方法並稍作更改以獲取 GMT+3 中的當前時間時,它會給我與 GMT 相同的結果嗎? 我不知道為什么:

public static Timestamp getCurrentTimeGMT3() {

    Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+3"));
    long time = c.getTimeInMillis();
    long offset = TimeZone.getDefault().getOffset(time);
    return new Timestamp(time - offset);

}

上面的代碼為什么不能正常工作的任何想法,以及如何做這樣的方法?

Timestamp擴展Date -它沒有一個時區,從概念。 它只是代表時間的瞬間。

如果要在具有特定時區的特定日歷中顯示它,則是格式問題。 創建具有相關時區的適當日歷,並在其中相應地設置時間戳。

(按照正常情況,我建議您在可能的情況下使用Joda Time而不是內置的API。它更加干凈。)

為什么從最后一行的時間中減去偏移量? 這基本上是將您的時間重新設置為格林尼治標准時間。 您檢索GMT + 3,然后減去3小時。

喬恩說了什么。 時間戳沒有時區,始終為UTC,因此實際上不應濫用它來表示本地時間。 如果您確實需要對象來表示本地時間,那么Joda Time可以提供一個類

而且您應該意識到,“ GMT + 3”不是真正的有效時區。 時區不僅具有基本偏移量,而且還具有夏令時偏移量,該偏移量對於具有相同基本偏移量的時區可能會有所不同,甚至可能由於法規而在相同時區發生變化。 實時區域ID是“歐洲/柏林”或“澳大利亞/達爾文”。

c.getTimeInMillis()返回自1970年1月1日UTC以來的毫秒數,並且無論Calendar實例中使用哪個時區,都將返回相同的值。

如果您創建帶有時區的日歷並需要訪問時間字段,則應直接訪問以下字段:

int h = c.get(Calendar.HOUR_OF_DAY);
int m = c.get(Calendar.MINUTE);
int s = c.get(Calendar.SECOND);

使用時區靜態方法。

TimeZone default = TimeZone.getDefault();

TimeZone.setDefault(TimeZone.getTimeZone("GMT+3"));
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(System.currentTimeMillis()));
Date date = cal.getTime(); // converted date time
System.out.println(date.toString());

// Set Back to System Default
TimeZone.setDefault(default);

示例代碼以獲取不同時區的時間

public class GetZoneDateTime {

public static void main(String[] args) throws Exception {
    String reqTzId = "Asia/Singapore";

    LocalDateTime now = LocalDateTime.now();
    System.out.println("Local Now: " + now + " TimeZone: " + TimeZone.getDefault());

    ZoneId zoneId = ZoneId.of(reqTzId);
    System.out.println("Req TimeZone : " + zoneId);

    LocalDateTime localNow = LocalDateTime.now(zoneId);
    System.out.println("tzLocalDateTime: " + localNow);

    ZonedDateTime zoneNow = ZonedDateTime.now(zoneId);
    System.out.println("tzZonedDateTime: " + zoneNow);
}

}

java.時間

2014 年 3 月, 現代日期時間 API取代了舊日期時間 API,從那時起強烈建議切換到java.time ,現代日期時間 API。

使用java.time的解決方案,現代日期時間 API:首先要了解的是timezonetimezone offset之間的區別。

時區由 ID 標識,通常采用地區/城市的形式,例如歐洲/倫敦。在這里您可以查看 tz 數據庫時區列表。 java.time API 提供ZonedDateTime來表示帶時區的日期時間。

時區偏移量告訴我們一個地方的時間與 UTC 的偏移量,例如 2011-12-03T10:15:30+01:00 告訴我們這個日期時間偏移了01:00小時從 UTC 即我們需要減去01:00小時以獲得 UTC 的等效日期時間。 java.time API 提供了OffsetDateTime來表示帶有時區偏移的日期時間。

一些時區遵守DST ,即 America/New_York 在冬季觀察到-05:00時的偏移,而在夏季觀察到-04:00時。 在這里你可以檢查一個插圖。

當我們創建具有固定偏移值的OffsetDateTime時, ZonedDateTime自動反映適用的偏移量。 因此,您問題中提到的GMTGMT+3不是時區,它們代表時區偏移。 一種更好更現代的寫法分別是Z+03:00

演示:

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

class Main {
    public static void main(String[] args) {
        ZoneId zone = ZoneId.of("America/New_York");

        // Current date-time in America/New_York
        System.out.println(ZonedDateTime.now(zone));

        // A sample winter date-time in America/New_York
        System.out.println(ZonedDateTime.of(LocalDate.of(2023, 01, 14), LocalTime.of(10, 20, 30), zone));

        // A sample summer date-time in America/New_York
        System.out.println(ZonedDateTime.of(LocalDate.of(2023, 06, 14), LocalTime.of(10, 20, 30), zone));

        // Current OffsetDateTime with an offset of 00:00 hours (UTC time)
        System.out.println(OffsetDateTime.now(ZoneOffset.UTC));

        // Current OffsetDateTime with an offset of 05:30 hours
        OffsetDateTime odt = OffsetDateTime.now(ZoneOffset.of("+05:30"));
        System.out.println(odt);
        // The same OffsetDateTime converted to UTC time (will be 05:30 less)
        System.out.println(odt.withOffsetSameInstant(ZoneOffset.UTC));
    }
}

樣本運行中的 Output:

2023-01-14T12:40:04.348474-05:00[America/New_York]
2023-01-14T10:20:30-05:00[America/New_York]
2023-06-14T10:20:30-04:00[America/New_York]
2023-01-14T17:40:04.352982Z
2023-01-14T23:10:04.353969+05:30
2023-01-14T17:40:04.353969Z

在線演示

Trail:Date Time了解有關現代日期時間 API 的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM