次の形式の日付があります:2010-03-01T00:00:00-08:00
それを解析するために、次のSimpleDateFormatをスローしました。
private static final SimpleDateFormat[] FORMATS = {
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"), //ISO8601 long RFC822 zone
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"), //ISO8601 long long form zone
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"), //ignore timezone
new SimpleDateFormat("yyyyMMddHHmmssZ"), //ISO8601 short
new SimpleDateFormat("yyyyMMddHHmm"),
new SimpleDateFormat("yyyyMMdd"), //birthdate from NIST IHE C32 sample
new SimpleDateFormat("yyyyMM"),
new SimpleDateFormat("yyyy") //just the year
};
次のような形式を使用する便利な方法があります。
public static Date figureOutTheDamnDate(String wtf) {
if (wtf == null) {
return null;
}
Date retval = null;
for (SimpleDateFormat sdf : FORMATS) {
try {
sdf.setLenient(false)
retval = sdf.parse(wtf);
System.out.println("Date:" + wtf + " hit on pattern:" + sdf.toPattern());
break;
} catch (ParseException ex) {
retval = null;
continue;
}
}
return retval;
}
パターンyyyyMMddHHmm
にヒットするようですが、日付をThu Dec 03 00:01:00 PST 2009
として返します。
この日付を解析する正しいパターンは何ですか?
更新:タイムゾーンの解析は必要ありません。ゾーン間を移動する時間依存の問題があるとは思いませんが、「-08:00」ゾーン形式を解析するにはどうすればよいですか????
単体テスト:
@Test
public void test_date_parser() {
System.out.println("\ntest_date_parser");
//month is zero based, are you effing kidding me
Calendar d = new GregorianCalendar(2000, 3, 6, 13, 00, 00);
assertEquals(d.getTime(), MyClass.figureOutTheDamnDate("200004061300"));
assertEquals(new GregorianCalendar(1950, 0, 1).getTime(), MyClass.figureOutTheDamnDate("1950"));
assertEquals(new GregorianCalendar(1997, 0, 1).getTime(), MyClass.figureOutTheDamnDate("199701"));
assertEquals(new GregorianCalendar(2010, 1, 25, 15, 19, 44).getTime(), MyClass.figureOutTheDamnDate("20100225151944-0800"));
//my machine happens to be in GMT-0800
assertEquals(new GregorianCalendar(2010, 1, 15, 13, 15, 00).getTime(),MyClass.figureOutTheDamnDate("2010-02-15T13:15:00-05:00"));
assertEquals(new GregorianCalendar(2010, 1, 15, 18, 15, 00).getTime(), MyClass.figureOutTheDamnDate("2010-02-15T18:15:00-05:00"));
assertEquals(new GregorianCalendar(2010, 2, 1).getTime(), MyClass.figureOutTheDamnDate("2010-03-01T00:00:00-08:00"));
assertEquals(new GregorianCalendar(2010, 2, 1, 17, 0, 0).getTime(), MyClass.figureOutTheDamnDate("2010-03-01T17:00:00-05:00"));
}
単体テストからの出力:
test_date_parser
Date:200004061300 hit on pattern:yyyyMMddHHmm
Date:1950 hit on pattern:yyyy
Date:199701 hit on pattern:yyyyMM
Date:20100225151944-0800 hit on pattern:yyyyMMddHHmmssZ
Date:2010-02-15T13:15:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-02-15T18:15:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-03-01T00:00:00-08:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
Date:2010-03-01T17:00:00-05:00 hit on pattern:yyyy-MM-dd'T'HH:mm:ss
JodaTime 's DateTimeFormat
救助する:
String dateString = "2010-03-01T00:00:00-08:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern);
DateTime dateTime = dtf.parseDateTime(dateString);
System.out.println(dateTime); // 2010-03-01T04:00:00.000-04:00
(toString()
の時間とタイムゾーンの違いは、GMT-4でロケールを明示的に設定しなかったからです)
Java.util.Date
になりたい場合は、DateTime#toDate()
を使用します。
Date date = dateTime.toDate();
を待つ JDK7( JSR-31 ) JSR-310、標準のJava SEでより優れたフォーマッタが必要な場合、参照実装は ThreeTen (Java 8になることを希望します)と呼ばれますAPI。実際、現在のSimpleDateFormat
はタイムゾーン表記でコロンを食べません。
Update:アップデートごとに、明らかにタイムゾーンは不要です。これはSimpleDateFormat
で動作するはずです。パターンでそれ(Z
)を省略します。
String dateString = "2010-03-01T00:00:00-08:00";
String pattern = "yyyy-MM-dd'T'HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date date = sdf.parse(dateString);
System.out.println(date); // Mon Mar 01 00:00:00 BOT 2010
(これは私のタイムゾーンに従って正しいです)
Java 7を使用した場合、次の日時パターンを使用できます。このパターンは、以前のバージョンのJavaではサポートされていないようです。
String dateTimeString = "2010-03-01T00:00:00-08:00";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
Date date = df.parse(dateTimeString);
詳細については、 SimpleDateFormat
documentation を参照してください。
ここに私が使用したスニペットがあります-プレーンSimpleDateFormat
で。他の誰かがそれから恩恵を受けることを願っています:
public static void main(String[] args) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") {
public StringBuffer format(Date date, StringBuffer toAppendTo, Java.text.FieldPosition pos) {
StringBuffer toFix = super.format(date, toAppendTo, pos);
return toFix.insert(toFix.length()-2, ':');
};
};
// Usage:
System.out.println(dateFormat.format(new Date()));
}
出力:
- Usual Output.........: 2013-06-14T10:54:07-0200
- This snippet's Output: 2013-06-14T10:54:07-02:00
SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
// Usage:
System.out.println(dateFormat2.format(new Date()));
出力:
- This pattern's output: 2013-06-14T10:54:07-02:00
そのためのドキュメント を参照してください。
これを試してください、その仕事は私のために:
Date date = javax.xml.bind.DatatypeConverter.parseDateTime("2013-06-01T12:45:01+04:00").getTime();
Java 8の場合:
OffsetDateTime dt = OffsetDateTime.parse("2010-03-01T00:00:00-08:00");
JDK 1.7以降を使用できる場合は、これを試してください。
public class DateUtil {
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
public static String format(Date date) {
return dateFormat.format(date);
}
public static Date parse(String dateString) throws AquariusException {
try {
return dateFormat.parse(dateString);
} catch (ParseException e) {
throw new AquariusException(e);
}
}
}
ドキュメント: https://docs.Oracle.com/javase/7/docs/api/Java/text/SimpleDateFormat.html 新しいタイムゾーン形式「XXX」をサポートします(例:-3:00 )
JDK 1.6は、「z」(例:NZST)、「zzzz」(例:ニュージーランド標準時)、「Z」(例:+1200)など、タイムゾーンの他の形式のみをサポートします。
acdcjuniorありがとうございます。 formatting and parsingの少し最適化されたバージョンを次に示します。
public static final SimpleDateFormat XML_SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.FRANCE)
{
private static final long serialVersionUID = -8275126788734707527L;
public StringBuffer format(Date date, StringBuffer toAppendTo, Java.text.FieldPosition pos)
{
final StringBuffer buf = super.format(date, toAppendTo, pos);
buf.insert(buf.length() - 2, ':');
return buf;
};
public Date parse(String source) throws Java.text.ParseException {
final int split = source.length() - 2;
return super.parse(source.substring(0, split - 1) + source.substring(split)); // replace ":" du TimeZone
};
};
Java 7.でXを使用できます。
https://docs.Oracle.com/javase/7/docs/api/Java/text/SimpleDateFormat.html
static final SimpleDateFormat DATE_TIME_FORMAT =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
static final SimpleDateFormat JSON_DATE_TIME_FORMAT =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
private String stringDate = "2016-12-01 22:05:30";
private String requiredDate = "2016-12-01T22:05:30+03:00";
@Test
public void parseDateToBinBankFormat() throws ParseException {
Date date = DATE_TIME_FORMAT.parse(stringDate);
String jsonDate = JSON_DATE_TIME_FORMAT.format(date);
System.out.println(jsonDate);
Assert.assertEquals(jsonDate, requiredDate);
}
setLenient(false)
を試してください。
補遺:さまざまな形式のDate
文字列を認識しているようです。エントリを行う必要がある場合は、これを見てみたいかもしれません 例 はInputVerifier
を拡張します。
Apache FastDateFormatの例(バージョンのドキュメントをクリックしてください: 2.6 and .5 )がここにありませんので、私はそれを必要とする人のために1つ追加しています。ここで重要なのは、パターンZZ
(2大文字Z
s)です。
import Java.text.ParseException
import Java.util.Date;
import org.Apache.commons.lang3.time.FastDateFormat;
public class DateFormatTest throws ParseException {
public static void main(String[] args) {
String stringDateFormat = "yyyy-MM-dd'T'HH:mm:ssZZ";
FastDateFormat fastDateFormat = FastDateFormat.getInstance(stringDateFormat);
System.out.println("Date formatted into String:");
System.out.println(fastDateFormat.format(new Date()));
String stringFormattedDate = "2016-11-22T14:30:14+05:30";
System.out.println("String parsed into Date:");
System.out.println(fastDateFormat.parse(stringFormattedDate));
}
}
コードの出力は次のとおりです。
Date formatted into String:
2016-11-22T14:52:17+05:30
String parsed into Date:
Tue Nov 22 14:30:14 IST 2016
注:上記のコードは、Apache Commonsのlang3のものです。クラスorg.Apache.commons.lang.time.FastDateFormat
は解析をサポートせず、フォーマットのみをサポートします。たとえば、次のコードの出力:
import Java.text.ParseException;
import Java.util.Date;
import org.Apache.commons.lang.time.FastDateFormat;
public class DateFormatTest {
public static void main(String[] args) throws ParseException {
String stringDateFormat = "yyyy-MM-dd'T'HH:mm:ssZZ";
FastDateFormat fastDateFormat = FastDateFormat.getInstance(stringDateFormat);
System.out.println("Date formatted into String:");
System.out.println(fastDateFormat.format(new Date()));
String stringFormattedDate = "2016-11-22T14:30:14+05:30";
System.out.println("String parsed into Date:");
System.out.println(fastDateFormat.parseObject(stringFormattedDate));
}
}
これになります:
Date formatted into String:
2016-11-22T14:55:56+05:30
String parsed into Date:
Exception in thread "main" Java.text.ParseException: Format.parseObject(String) failed
at Java.text.Format.parseObject(Format.Java:228)
at DateFormatTest.main(DateFormatTest.Java:12)
日付文字列が2018-07-20T12:18:29.802Zの場合
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");