9

String 型のタイムスタンプがあり、それを double に変換しようとしています (結果は数秒で見つかります)。

double mytimeStamp = 0;

String timeStamp = new SimpleDateFormat(" mm ss S").format(new Date( ));   

SimpleDateFormat dateFormat = new SimpleDateFormat(" mm ss S");

try {
  mytimeStamp = ((double)dateFormat.parse(timeStamp).getTime())/1000;
} catch (ParseException e1) {
  // TODO Auto-generated catch block
  e1.printStackTrace();
}

System.out.println("timeStamp is: "+ mytimeStamp);

問題は、次のような値を取得することです。その-2722.515理由はわかりません。

なんでマイナスなの?

コードに何か問題がありますか?

このタイムスタンプを変換するmm ss Sと、リアルタイムと一致せず、これは別の問題のようです!

4

2 に答える 2

1

---実際には、これを行うためのはるかに優れた方法がありますが、日付を使用する場合は、事前編集の回答にスキップしてください---

日付は実際にはあなたが望むことをしません。それは実際のカレンダーから時間を選ぶ実際の必要性の外の時間計算であるように見えます。

グレゴリオ暦に追いつくためにDatesがしなければならない厄介な特別な処理をすべて避けるために、独自のクラスを作成する方がはるかに良いでしょう。この特別な処理には、タイムゾーンの認識、夏時間、宣言された「スキップされた日」、うるう秒、うるう年などが含まれます(ただしこれらに限定されません)。

public TimeOnly {

   private long timestamp;
   private int millis;
   private int seconds;
   ... etc ...

   public TimeOnly(int hours, int minutes, int seconds, int millis) {
     this.timestamp = millis + seconds * 1000L + minutes * 60000L + hours * 3600000L; 
     this.millis = millis;
     this.seconds = seconds;
     ... etc ...
   }

   private TimeOnly(long timestamp) {
     this.timestamp = timestamp;
     this.millis = timestamp % 1000;
     this.seconds = timestamp % 60000L - this.millis;
     ... etc ...
   }

   public long getTimestamp() {
     return timestamp;
   }

   public int getMillis() {
     return millis;
   }

   public int getSeconds() {
     return seconds;
   }

   ... etc ...
}

public TimeFormatter {

  public TimeFormatter() {

  }

  public String format(Time time) {
    StringBuilder builder = new StringBuilder();
    builder.append(String.valueOf(time.getHours()));
    builder.append(":");
    builder.append(String.valueOf(time.getMinutes()));
    builder.append(":");
    builder.append(String.valueOf(time.getSeconds()));
    builder.append(".");
    if (time.getMillis() < 10) {
      builder.append("00");
    } else if (time.getMillis() < 100) {
      builder.append("0");
    }
    builder.append(time.getMillis());
    return builder.toString();
}

この解決策は、車輪の再発明のように見えるかもしれませんが、実際には、八角形を車輪として使用することを避けています。限られた範囲の値でDateを機能させることはできますが、Dateの動作は希望どおりではないようです。

本当に凝ったものにしたいのなら、上記の実装を比較できるようにすることなどができます。しかし、私は物事に反対することをお勧めします。構築後に更新メソッドを提供しないでください。これにより、かなり厄介な再計算が強制され、コードの保守が困難になります。代わりに、実装したい操作に応答して新しいTimeOnlyを返すメソッドを提供してください。

public TimeOnly addSeconds(int value) {
  int stamp = this.timestamp;
  stamp += value * 60000L;
  if (stamp < timestamp) {
    throw new Excepton("overflow");
  }
  return new TimeOnly(stamp);
}

また、使用しないものを実装しないでください。未使用のコードは、バグにとって肥沃な土壌になる傾向があります。

そしてもちろん、すべての「時間」の答えは、さまざまな種類の時間測定をすべて区別するJodaTimeの使用を検討してください。ただし、このような小さな問題の場合は、戦車を使用してアリを殺すのと似ています。

---事前編集の回答---

時間(年、月、日、時、分、秒、ミリ秒)の完全な指定がない場合、最初のステップでフォーマットされた時間値には、指定されていない多くのフィールドが含まれます。それらのフィールドに入るのはおそらくゴミでしょう。

次に、オブジェクトgetTime()全体に作用してDate、有効なフィールドとガベージの両方を値に変換します。ガベージは、有効な値を変更することもあります(フィールドが相互作用するため、96秒= 1分36秒)。

これを実行する最善の方法は、すべての「時間のみ」の日付を1つの既知の日に初期化することです。したがって、比較と数学演算(is、3 11 23> 1 02 10?)を実行すると、一貫した結果が得られます(yes、3 11 23> 1 02 10、実際には2013 02 10 00 03 11 23>2013 02 10 00 03 11 232013 02 10 00 03 11 23比較されません2000 02 10 00 03 11 23

使用する日を選択するときは、2月29日に隣接する日、夏時間のシフトに近い日などを避けてください。

于 2013-02-21T13:56:53.353 に答える