34

datetimeHTML5入力フィールドから値として返された日付を解析しようとしています。例を見るには、Operaで試してみてください。返される日付は次のようになります2011-05-03T11:58:01Z

これをJavaの日付またはカレンダーオブジェクトに解析したいと思います。

理想的には、ソリューションには次のものが必要です。

  • 外部ライブラリ(jar)はありません
  • 受け入れ可能なすべてのRFC3339形式を処理します
  • 文字列は、RFC3339の有効な日付であるかどうかを確認するために簡単に検証できる必要があります
4

9 に答える 9

30
于 2018-04-03T21:40:52.967 に答える
15

したがって、原則として、これはさまざまなSimpleDateFormatパターンを使用して行われます。

RFC3339の個々の宣言のパターンのリストは次のとおりです。

  • 日付-完全に耳: yyyy
  • 日付-月: MM
  • 日付-月曜日: dd
  • 時間-時間: HH
  • 時間-分: mm
  • 時間秒: ss
  • time-secfrac :( .SSS ミリS秒を意味しますが、これらが3桁より多いまたは少ない場合に何が起こるかは明確ではありません。)
  • time-numoffset :(+02:00サポートされていないようです-代わりに、フォーマットをサポートし+0200GMT+02:00とを使用するいくつかの名前付きタイムゾーンをサポートzしますZ。)
  • タイムオフセット:( 'Z' 他のタイムゾーンはサポートされていません)-これを使用するformat.setTimezone(TimeZone.getTimeZone("UTC"))前に使用する必要があります。)
  • 部分時間: HH:mm:ssまたはHH:mm:ss.SSS
  • フルタイム: HH:mm:ss'Z'またはHH:mm:ss.SSS'Z'
  • フルデート: yyyy-MM-dd
  • 日時: yyyy-MM-dd'T'HH:mm:ss'Z'またはyyyy-MM-dd'T'HH:mm:ss.SSS'Z'

ご覧のとおり、これではすべてを解析できるわけではないようです。おそらく、最初から実装する方がよいでしょうRFC3339DateFormat(簡単にするために正規表現を使用するか、効率を上げるために手動で解析します)。

于 2011-05-18T01:23:51.060 に答える
13

グーグルがグーグルHTTPクライアントライブラリにRfc3339パーサーを実装していることがわかりました

https://github.com/google/google-http-java-client/blob/dev/google-http-client/src/main/java/com/google/api/client/util/DateTime.java

テスト済み。さまざまなサブ秒の時間フラグメントを解析するのに適しています。

import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;

import com.google.api.client.util.DateTime;

DateTimeFormatter formatter = DateTimeFormatter
            .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
            .withZone(ZoneId.of("UTC"));

@Test
public void test1e9Parse() {
    String timeStr = "2018-04-03T11:32:26.553955473Z";

    DateTime dateTime = DateTime.parseRfc3339(timeStr);
    long millis = dateTime.getValue();

    String result = formatter.format(new Date(millis).toInstant());

    assert result.equals("2018-04-03T11:32:26.553Z");
}

@Test
public void test1e3Parse() {
    String timeStr = "2018-04-03T11:32:26.553Z";

    DateTime dateTime = DateTime.parseRfc3339(timeStr);
    long millis = dateTime.getValue();

    String result = formatter.format(new Date(millis).toInstant());

    assert result.equals("2018-04-03T11:32:26.553Z");
}

@Test
public void testEpochSecondsParse() {

    String timeStr = "2018-04-03T11:32:26Z";

    DateTime dateTime = DateTime.parseRfc3339(timeStr);
    long millis = dateTime.getValue();

    String result = formatter.format(new Date(millis).toInstant());

    assert result.equals("2018-04-03T11:32:26.000Z");
}
于 2018-04-03T16:03:27.743 に答える
2

あなたが持っているフォーマット、例えば2011-05-03T11:58:01Zでは、以下のコードで十分です。ただし、最近ChromeとOperaでhtml5 datetimeを試してみたところ、2011-05-03T11:58Z->以下のコードで処理できないss部分がありません。

new Timestamp(javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(date).toGregorianCalendar().getTimeInMillis());
于 2011-08-16T08:16:06.910 に答える
2

おそらく最もエレガントな方法ではありませんが、確かに私が最近作った方法で機能します:

Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
cal.setTime(sdf.parse(dateInString.replace("Z", "").replace("T", "-")));
于 2017-01-10T12:54:15.267 に答える
1

将来の参考のために、別の方法として、手書きのITU [1]を使用して、RFC-3339の解析を正確に処理し、うるう秒を簡単に処理することもできます。ライブラリは依存関係がなく、重量は18kBのみです。

完全開示:私は著者です

try 
{
    final OffsetDateTime dateTime = ITU.parseDateTime(dateTimeStr);
}
catch (LeapSecondException exc) 
{
  // The following helper methods are available let you decide how to progress
  //int exc.getSecondsInMinute()
  //OffsetDateTime exc.getNearestDateTime()
  //boolean exc.isVerifiedValidLeapYearMonth()
}

[1] -https://github.com/ethlo/itu

于 2022-02-28T10:49:26.420 に答える
0

私はこれを使用しています:

DateTimeFormatter RFC_3339_DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
            .append(ISO_LOCAL_DATE_TIME)
            .optionalStart()
            .appendOffset("+HH:MM", "Z")
            .optionalEnd()
            .toFormatter();

例:

String dateTimeString = "2007-05-01T15:43:26.3452+07:00";
ZonedDateTime zonedDateTime = ZonedDateTime.from(RFC_3339_DATE_TIME_FORMATTER.parse(dateTimeString));
于 2020-07-26T14:33:43.193 に答える
0

ただし、質問は非常に古いものですが、この回答のKotlinバージョンが必要な場合に役立つ可能性があります。このファイルを使用することにより、誰でもRfc3339の日付を任意の日付形式に変換できます。ここでは、空のファイル名を取り、3つの引数を持つDateUtilという関数を作成します。getDateString()

1st argument : Your input date
2nd argument : Your input date pattern
3rd argument : Your wanted date pattern

DateUtil.kt

object DatePattern {
    const val DAY_MONTH_YEAR = "dd-MM-yyyy"
    const val RFC3339 = "yyyy-MM-dd'T'HH:mm:ss'Z'"
}

fun getDateString(date: String, inputDatePattern: String, outputDatePattern: String): String {
    return try {
        val inputFormat = SimpleDateFormat(inputDatePattern, getDefault())
        val outputFormat = SimpleDateFormat(outputDatePattern, getDefault())

        outputFormat.format(inputFormat.parse(date))
    } catch (e: Exception) {
        ""
    }
}

そして今、あなたのactivity / fuction / dataSourse Mapperでこのメソッドを使用して、このような文字列形式で日付を取得します

getDate("2022-01-18T14:41:52Z", RFC3339, DAY_MONTH_YEAR)

出力は次のようになります

18-01-2022
于 2022-01-18T10:03:29.523 に答える
-1
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(datetimeInFRC3339format)
于 2018-02-14T11:55:54.090 に答える