5

SimpleDateFormat以下に示すように、オブジェクトとオブジェクトを使用していDateます。問題は、Dateオブジェクトが間違った日付を示していることです。これは、元の文字列から数分ずれています。このDateオブジェクトは、デバッガーに合計ミリ秒単位で時間を格納しているように見えます。

問題に関するアイデアはありますか?

import java.text.SimpleDateFormat;

import java.util.Date;

Date played_at_local; 

dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSSSSZ");

played_at_local = dateFormat.parse("2011-04-11T22:27:18.491726-05:00"); 

//played_at_local shows "Mon Apr 11 22:35:29 America/Chicago 2011" in debugger
4

7 に答える 7

15

フォーマット文字列から小数秒を削除してみてください。同じ問題に遭遇しましたが、形式が少し異なります。私の入力形式は ISO 形式ではありませんでした (「T」も「Z」もありません) が、症状は同じでした。時間はランダムな分数と秒数だけずれていましたが、それ以外はすべて問題ありませんでした。これは私のログ結果がどのように見えるかです:

小数秒形式を使用する場合:

SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");

# Parsed date: 2011-05-27 17:11:15.271816 => Fri May 27 17:15:46 EDT 2011
# Parsed date: 2011-05-27 17:09:37.750343 => Fri May 27 17:22:07 EDT 2011
# Parsed date: 2011-05-27 17:05:55.182921 => Fri May 27 17:08:57 EDT 2011
# Parsed date: 2011-05-27 16:55:05.69092 => Fri May 27 16:56:14 EDT 2011
# Parsed date: 2011-05-27 16:38:35.50348 => Fri May 27 16:39:25 EDT 2011

フォーマットから小数秒を削除して修正しました。

SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

# Parsed date: 2011-05-27 17:11:15.271816 => Fri May 27 17:11:15 EDT 2011
# Parsed date: 2011-05-27 17:09:37.750343 => Fri May 27 17:09:37 EDT 2011
# Parsed date: 2011-05-27 17:05:55.182921 => Fri May 27 17:05:55 EDT 2011
# Parsed date: 2011-05-27 16:55:05.69092 => Fri May 27 16:55:05 EDT 2011
# Parsed date: 2011-05-27 16:38:35.50348 => Fri May 27 16:38:35 EDT 2011

私が考えているのは、入力文字列の「小数秒」部分が長すぎることです (OP の例でも同じです)。小数点以下3桁のみを想定しているようです。計算を行う場合 (最初の例を取り上げます):

  • 小数秒 = 0.271816 秒
  • DateFormat が見るのは271816 / 1000秒です
  • 271816 / 1000 == 271 秒
  • 271 / 60 = 4 分
  • 271 % 60 = 31 秒
  • 17:11:15 から 17:15:46 はちょうど 4 分 31 秒ずれています
于 2011-05-27T21:25:54.873 に答える
1

コードには 3 つの主要な問題があります。

  1. はミリ秒を超える精度をサポートしていません ( .SSSSSS) 。また、1 秒未満の桁数を 3 桁に制限する必要があることも意味します。SimpleDateFormat.SSS
  2. Zタイムゾーン オフセットの解析に使用しましたが、-05:00これの正しいパターンは ですXXX
  3. 24 時間形式で時間を使用hhしましたが、これの正しいパターンは ですHH。記号hhは、12 時間形式 (つまり、午前/午後) 形式で時間に使用されます。

これとは別にLocale、日付時刻文字列の一部は s ごとに異なる方法で表現されるため、常に日付の解析/書式設定 API を使用することをお勧めしますLocale

デモ:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
        Date date = sdf.parse("2011-04-11T22:27:18.491-05:00");

        // Print the default string i.e. Date#toString
        System.out.println(date);

        // Print the date-time in a custom format
        sdf.setTimeZone(TimeZone.getTimeZone("GMT-05:00"));
        System.out.println(sdf.format(date));
    }
}

出力:

Tue Apr 12 04:27:18 BST 2011
2011-04-11T22:27:18.491-05:00

従来の日時 API に関するいくつかの事実:

  1. オブジェクトは、最新の日時型のような実際のjava.util.Date日時オブジェクトではありません。むしろ、「エポック」(または UTC) として知られる標準ベース時刻からのミリ秒数を表します。のオブジェクトを出力すると、そのメソッドは、このミリ秒値から計算された JVM のタイムゾーンで日時を返します。異なるタイムゾーンで日時を出力する必要がある場合は、タイムゾーンを に設定し、そこからフォーマットされた文字列を取得する必要があります。January 1, 1970, 00:00:00 GMTjava.util.DatetoStringSimpleDateFormat
  2. java.util日時 API とそのフォーマット APIはSimpleDateFormat時代遅れで、エラーが発生しやすいものです。それらの使用を完全に停止し、最新の日時 APIに切り替えることをお勧めします*

最新の日時 API を使用する:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = OffsetDateTime.parse("2011-04-11T22:27:18.491726-05:00");

        // Print the default string i.e. OffsetDateTime#toString
        System.out.println(odt);

        // Print the date-time in a custom format. Note: OffsetDateTime#toString drops
        // seconds if it is zero
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSSSSXXX");
        System.out.println(dtf.format(odt));
    }
}

出力:

2011-04-11T22:27:18.491726-05:00
2011-04-11T22:27:18.491726-05:00

注:の場合DateTimeFormatter、記号はuを意味し、記号は紀元年を意味します。[AD][2] 時代の 1 年間は問題ありませんが、BC 時代の 1 年間は問題になります。詳細については、この回答を確認してください。y

最新の日時 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-03-27T10:43:40.093 に答える
1

これを試してください、私のために働いていますZは日付で使用するか、フォーマット文字列からrmoveする必要があります

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSSSS'Z'");

played_at_local = dateFormat.parse("2011-04-11T22:27:18.491726Z-05:00");
于 2011-04-12T14:19:33.610 に答える
0

05:00 -->> 0500

hh --> HH // error not because of this ,but date is in 24hr format.

played_at_local = dateFormat.parse("2011-04-11T22:27:18.491726-05:00"); 

する必要があります

played_at_local = dateFormat.parse("2011-04-11T22:27:18.491726-0500"); 
于 2011-04-12T14:12:45.757 に答える
0

これを試して :

dTime  =  new  SimpleDateFormat("HH:mm:ss:SS");
String  sTime =  (dTime.format(new java.util.Date())).toString();

この助けを願っています

于 2014-11-28T10:48:31.450 に答える
0

この方法を試すことができます: http://docs.oracle.com/javase/6/docs/api/java/sql/Timestamp.html#valueOf(java.lang.String)

重要なことは、小数桁はオプションであり、可変数を使用できることです。ただし、これはタイムゾーンを考慮していないようです。

ドキュメントから:

valueOf

public static Timestamp valueOf(String s)
Converts a String object in JDBC timestamp escape format to a Timestamp value.
Parameters:
s - timestamp in format yyyy-mm-dd hh:mm:ss[.f...]. The fractional seconds may be omitted.
Returns:
corresponding Timestamp value
Throws:
IllegalArgumentException - if the given argument does not have the format yyyy-mm-dd hh:mm:ss[.f...]
于 2013-02-28T07:04:26.630 に答える