44

PST オフセットを含むタイムスタンプを出力したい (例: 2008-11-13T13:23:30-08:00)。時間:分のjava.util.SimpleDateFormat形式でタイムゾーン オフセットを出力していないようです。コロンは除外されています。Javaでそのタイムスタンプを取得する簡単な方法はありますか?

// I want 2008-11-13T12:23:30-08:00
String timestamp = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").format(new Date());
System.out.println(timestamp); 
// prints "2008-11-13T12:23:30-0800" See the difference?

また、SimpleDateFormat上記の例を正しく解析できません。をスローしParseExceptionます。

// Throws a ParseException
new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").parse("2008-11-13T13:23:30-08:00")
4

12 に答える 12

19

Joda Timeパッケージをチェックしてください。これにより、RFC 3339 の日付の書式設定が非常に簡単になります。

ジョーダの例:

DateTime dt = new DateTime(2011,1,2,12,45,0,0, DateTimeZone.UTC);
DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
String outRfc = fmt.print(dt);
于 2008-11-14T12:28:31.857 に答える
15

同じ問題に対する答えを探すのにかなりの時間を費やしましたが、ここで何かを見つけました: http://developer.android.com/reference/java/text/SimpleDateFormat.html

推奨される答え:

String timestamp = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZZZZZ").format(new Date());

お気付きかもしれませんが、私は 1 つではなく 5 つの「Z」を使用しています。これにより、「2008-11-13T12:23:30-08:00」のようにオフセットにコロンが含まれた出力が得られます。それが役に立てば幸い。

于 2015-05-20T09:52:13.920 に答える
15

「やり遂げる部門」からの1つの解決策は、SimpleDateFormatが完了した後に正規表現を使用して文字列を修正することです。Perl の s/(\d{2})(\d{2})$/$1:$2/ のようなもの。

これに少しでも興味がある場合は、この応答を実際の Java コードで編集します。

しかし、ええ。私もこの問題にぶつかっています。RFC3339、あなたを見ています!

編集:

これは私のために働く

// As a private class member
private SimpleDateFormat rfc3339 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

String toRFC3339(Date d)
{
   return rfc3339.format(d).replaceAll("(\\d\\d)(\\d\\d)$", "$1:$2");
}
于 2012-07-16T19:29:47.913 に答える
4

問題は、Zが区切り文字としてコロン(:)を使用せずにタイムゾーンオフセットを生成することです。

于 2009-02-02T17:07:14.093 に答える
3
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ss.SZ");

まさにあなたが必要としているものではありませんか?

于 2008-11-14T05:39:25.553 に答える
1

RFC3339のInternetDateFormatクラスを作成しました。

ただし、ソースコードのコメントは日本語です。

PS:英語版を作成し、少しリファクタリングしました。

于 2013-05-17T00:57:55.370 に答える
1

java.time

java.utilDate-Time API とその書式設定 APIはSimpleDateFormat時代遅れで、エラーが発生しやすいものです。それらの使用を完全に停止し、最新の Date-Time APIに切り替えることをお勧めします*

また、以下はJoda-Timeのホームページからの通知です。

Java SE 8 以降では、このプロジェクトを置き換える JDK のコア部分である java.time (JSR-310) に移行するように求められることに注意してください。

java.time最新の Date-Time APIを使用したソリューション:太平洋タイム ゾーンで最大の都市はロサンゼルスで、そのタイムゾーン名はAmerica/Los_Angelesです。を使用して、 DST移行時にタイムゾーン オフセットを自動的に調整するように設計されZoneId.of("America/Los_Angeles")た のインスタンスを作成できます 。ZonedDateTime

タイムゾーン名ではなくタイムゾーン オフセットが必要な場合は、 aZonedDateTimeOffsetDateTimeusingに変換できますZonedDateTime#toOffsetDateTime。のその他の用途としてOffsetDateTimeは、固定のタイムゾーン オフセットを使用して Date-Time インスタンスを作成すること (たとえばInstant.now().atOffset(ZoneOffset.of("+05:30"))、 や、タイムゾーン オフセットを使用して Date-Time 文字列を解析すること) があります。

デモ:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        ZoneId zoneIdLosAngeles = ZoneId.of("America/Los_Angeles");
        ZonedDateTime zdtNowLosAngeles = ZonedDateTime.now(zoneIdLosAngeles);
        System.out.println(zdtNowLosAngeles);

        // With zone offset but without time zone name
        OffsetDateTime odtNowLosAngeles = zdtNowLosAngeles.toOffsetDateTime();
        System.out.println(odtNowLosAngeles);

        // Truncated up to seconds
        odtNowLosAngeles = odtNowLosAngeles.truncatedTo(ChronoUnit.SECONDS);
        System.out.println(odtNowLosAngeles);

        // ################ A winter date-time ################
        ZonedDateTime zdtLosAngelesWinter = ZonedDateTime
                .of(LocalDateTime.of(LocalDate.of(2021, 11, 20), LocalTime.of(10, 20)), zoneIdLosAngeles);
        System.out.println(zdtLosAngelesWinter); // 2021-11-20T10:20-08:00[America/Los_Angeles]
        System.out.println(zdtLosAngelesWinter.toOffsetDateTime()); // 2021-11-20T10:20-08:00

        // ################ Parsing a date-time string with zone offset ################
        String strDateTime = "2008-11-13T13:23:30-08:00";
        OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
        System.out.println(odt); // 2008-11-13T13:23:30-08:00
    }
}

サンプル実行からの出力:

2021-07-18T03:27:15.578028-07:00[America/Los_Angeles]
2021-07-18T03:27:15.578028-07:00
2021-07-18T03:27:15-07:00
2021-11-20T10:20-08:00[America/Los_Angeles]
2021-11-20T10:20-08:00
2008-11-13T13:23:30-08:00

ONLINE DEMO

DateTimeFormatterあなたの質問の日時文字列を解析するためにa を使用していないことに気付いたに違いありません。これは、日時文字列が ISO-8601 標準に準拠しているためです。最新の Date-Time API はISO 8601に基づいてDateTimeFormatterおり、Date-Time 文字列が ISO 8601 標準に準拠している限り、オブジェクトを明示的に使用する必要はありません。

最新の Date-Time API の詳細については、Trail: Date Timeを参照してください。


* 何らかの理由で、Java 6 または Java 7 に固執する必要がある場合は、 java.time機能のほとんどを Java 6 & 7 にバックポートするThreeTen-Backportを使用できます。Androidプロジェクトと Android API で作業している場合レベルはまだ Java-8 に準拠していません。desugarで利用できる Java 8+ APIと Android プロジェクトで ThreeTenABP を使用する方法 を確認してください。

于 2021-07-18T10:40:50.920 に答える
1

問題を解決するのに役立つ迷子の PasteBin を見つけました: http://pastebin.com/y3TCAikc

その内容が後で削除された場合に備えて:

// I want 2008-11-13T12:23:30-08:00
String timestamp = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").format(new Date());
System.out.println(timestamp); 
// prints "2008-11-13T12:23:30-0800" See the difference?

// Throws a ParseException
new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").parse("2008-11-13T13:23:30-08:00")

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ss.SZ");
于 2012-08-15T02:10:59.603 に答える