簡體   English   中英

像在UTC中一樣解析ISO 8601字符串本地日期時間

[英]Parsing an ISO 8601 string local date-time as if in UTC

在Java中,我需要使用以下格式的String來創建Calendar對象:

yyyy-MM-dd'T'HH:mm:ss

該字符串將始終設置為GMT時間。 所以這是我的代碼:

    public static Calendar dateDecode(String dateString) throws ParseException
{
    TimeZone t = TimeZone.getTimeZone("GMT");
    Calendar cal = Calendar.getInstance(t);
    date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    Date d = date.parse(dateString);
    cal.setTime(d);
    return cal;
}

接着:

Calendar cal = Calendar.getInstance();
    try
    {
        cal = dateDecode("2002-05-30T09:30:10");
    } catch (ParseException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    int month =  cal.get(Calendar.MONTH)+1;

我得到以下輸出:

Timezone: GMT+00:00 date: 2002-5-30 time: 7:30:10

如您所見,這是錯誤的,因為提供的時間是格林尼治標准時間而不是CET。 我認為發生的事情是,它認為所提供的時間在CET(這是我當前的時區)中,因此將時間從CET轉換為GMT,因此從最終結果中減去了兩個小時。

有人可以幫我嗎?

謝謝

順便說一句:出於各種原因,我不想使用JodaTime。

以下是一些代碼,可以幫助您在解析時區之前對其進行設置:

// sdf contains a Calendar object with the default timezone.
Date date = new Date();
String formatPattern = ....;
SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);

TimeZone T1;
TimeZone T2;
....
....
// set the Calendar of sdf to timezone T1
sdf.setTimeZone(T1);
System.out.println(sdf.format(date));

// set the Calendar of sdf to timezone T2
sdf.setTimeZone(T2);
System.out.println(sdf.format(date));

// Use the 'calOfT2' instance-methods to get specific info
// about the time-of-day for date 'date' in timezone T2.
Calendar calOfT2 = sdf.getCalendar();

我發現的另一個類似問題也可能會有所幫助: 如何在Java中設置默認時區並控制日期在DB上的存儲方式?

編輯:

這也是有關Java和日期的出色教程: http : //www.tutorialspoint.com/java/java_date_time.htm

ISO 8601

您的字符串格式恰好符​​合ISO 8601標准。

如果確定日期時間值的字符串用於UTC,而不是其他自UTC或時區的偏移量,則應在末尾帶有Z ZZulu縮寫,表示UTC

String input = "2002-05-30T09:30:10" + "Z" ;

解析/生成字符串時,默認情況下java.time類使用標准ISO 8601格式。 因此,無需指定格式化模式。

Instant

Instant類以UTC表示時間軸上的時刻,分辨率為納秒 (最多十進制的九(9)位數字)。

Instant instant = Instant.parse( "2002-05-30T09:30:10" + "Z" );

Instant.toString():2002-05-30T09:30:10Z

ZonedDateTime

如果要看到與特定區域的掛鍾時間相同的時刻,請應用ZoneId以獲取ZonedDateTime對象。

continent/region的格式指定正確的時區名稱 ,例如America/MontrealAfrica/CasablancaPacific/Auckland 切勿使用3-4字母的縮寫,例如CETESTIST因為它們不是真實的時區,不是標准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = instant.atZone( z );

zdt.toString():2002-05-30T11:30:10 + 02:00 [歐洲/巴黎]

看到此代碼在IdeOne.com上實時運行


關於java.time

java.time框架內置於Java 8及更高版本中。 這些類取代了麻煩的舊的舊式日期時間類,例如java.util.DateCalendarSimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time類。

要了解更多信息,請參見Oracle教程 並在Stack Overflow中搜索許多示例和說明。 規格為JSR 310

在哪里獲取java.time類?

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目為將來可能在java.time中添加內容提供了一個試驗場。 您可以在這里找到一些有用的類,比如IntervalYearWeekYearQuarter ,和更多

暫無
暫無

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

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