0

オブジェクトの createdAt タイムスタンプを parse.com から 2014-08-01T01:17:56.751Z として取得しています。それを相対時間に変換するクラスがあります。

public static String timeAgo(String time){
  PrettyTime mPtime = new PrettyTime();

  long timeAgo = timeStringtoMilis(time);

  return mPtime.format( new Date( timeAgo ) );
}

public static long timeStringtoMilis(String time) {
  long milis = 0;

  try {
    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date   = sd.parse(time);
    milis       = date.getTime();
  } catch (Exception e) {
    e.printStackTrace();
  }

  return milis;
}

問題は、これが日付を間違って解析することです。現在、結果は40年前と言っていますが、これは非常に間違っています. 私は何を間違っていますか?

4

2 に答える 2

3

現在の日付形式"yyyy-MM-dd HH:mm:ss"は、指定された例では機能しません2014-08-01T01:17:56.751Z。フォーマットに文字TZミリ秒がありません。次のように変更します。

new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

それを修正します。

の JavaDoc の例も確認してSimpleDateFormatください。例の正しい日付形式も示されているためです: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

于 2014-10-26T09:45:08.027 に答える
3

@Tomの答えを拡張する:

問題

「Z」をハードコーディングする場合、すべての日付が UTC として保存されていると想定しますが、必ずしもそうである必要はありません。

問題は、SimpleDateFormat がリテラルを UTC の「-0000」オフセットのエイリアスとして認識しないことです'Z'(何らかの理由で、ISO-8601 に準拠していると主張しているため)。

だからあなたはできません

new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

これは、すべての日付が常に UTC で記述されると誤って想定しているためですが、それはできません。

new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

これは、リテラル「Z」が発生した日付を解析できないためです。

解決策 1: javax.xml.bind.DatatypeConverter を使用する

このデータ型コンバーターは、実際にISO8601 に準拠しており、次のように簡単に使用できます。

import javax.xml.bind.DatatypeConverter;

public Long isoToMillis(String dateString){
  Calendar calendar = DatatypeConverter.parseDateTime(dateString);
  return calendar.getTime().getTime();
}

とにかくJAXBを使用する場合は、それが道です。

解決策 2: 条件付き書式を使用する

final static String ZULUFORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
final static String OFFSETFORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";

/* This is a utility method, so you want the calling method
 * to be informed that something is wrong with the input format
 */
public static Long isoToMillis(String dateString) throws ParseException{

  /* It is the default, so we should use it by default */
  String formatString = ZULUFORMAT;

  if(! dateString.endsWith("Z") ) {
    formatString = OFFSETFORMAT;
  }
  
  SimpleDateFormat sd = new SimpleDateFormat(formatString);
  return sd.parse(dateString).getTime();

}

まだ JAXB を使用していない場合は、このメソッドをユーティリティ クラスに追加することをお勧めします。

于 2014-10-26T10:37:21.150 に答える