2012-03-12 10 views
1

外部ライブラリを使用せずに、HH:mm:ssの形式でJLabelの表示値を使用したいと考えています。longをHH:mm:ssに変換してラベルに表示する最も効率的な方法は何ですか?

Seconds:        Output: 
-------------------------------------------------- 
long seconds = 0     00:00:00 
long seconds = 5     00:00:05 
long seconds = 500     00:08:20 
long seconds = 5000     01:23:20 

Note: the seconds value is of type long 



私は、通常、1つは、次の操作を行うだけだろうと承知している:

だから例えば、数秒で次の入力し、所望の出力は以下の通りです(ラベルは毎秒更新されます)希望の番号を取得するための変換:

long s = 5000;    //total seconds 

long hrs = (s/3600)  //hours 
long mins = ((s%3600)/60) //minutes 
long secs = (s%60)   //seconds 



はしかし、これは値に小数を残します。おそらく、私に不必要な小数を投げることを可能にする何らかの整形があります。

私が遭遇したオプションはString.format(),SimpleDateFormat()であり、文字列を自分自身で連結しています。

私はこのJLabelを毎秒更新していますが、それ以上の場合は5-6日に相当することがあります。

私は、私よりも多くの経験があり、この問題に取り組む最も効率的な方法を知っている人を探しています。

+2

再: "時々それは5-6日の同等に数えることができます":00::その場合には、それが戻っ '00にラップアラウンドう00、何日かの日数を表示したいですか? – ruakh

+1

Re: "しかし、これは値に小数点以下の桁を残します":あなたが意味することはわかりません。 Javaでは、 's'が' long'の場合、 's/3600'はlongです。 [整数除算](http://mathworld.wolfram.com/IntegerDivision.html)を実行するので、小数点は生成されません。 – ruakh

+0

@ruakh私は日カテゴリを追加する必要があるかもしれませんが、まだ遭遇していません。私は将来私がそれに遭遇することを知っています。今のところ、私はちょうど少なくとも分、秒、秒を適切に表示できるようにしたかったのです。長い間、私はJavaではなくGroovyで簡単にテストしましたが、おそらくそれが小数点を示した理由を知らないで型を変換したでしょう。 (私があなたがそれを指摘するまで気づいていなかった) – StartingGroovy

答えて

1

フォーマッタクラスを使用したくない場合は、ラッパークラスと文字列操作の間の変換などの基本操作を使用して作業を完了できます。このコードを見てみましょう:

long h, m, s; // Initialize them after calculation. 
String h1, m1, s1; 

h1 = Long.toString(h); 
m1 = Long.toString(m); 
s1 = Long.toString(s); 

if (s1.length() < 2) 
    s1 = "0" + s1; 
if (m1.length() < 2) 
    m1 = "0" + m1; 
if (h1.length() < 2) 
    h1 = "0" + h1; 

String output = h1+":"+m1+":"+s1; 

では、秒、分、時間の正しく計算値を持っていると仮定すると、あなたは、単純な長さのチェックでそれらをフォーマットし、最終的にはこれらを連結し、その後、これらの変数の文字列バージョンを収集することができます時間単位の部品。

+0

私はこの方法も好きです。 24時間以上の値でも動作します(対処が必要な場合)。 – StartingGroovy

+0

@StartingGroovyゲームの実装にこのメソッドを使用していましたが、私はあなたが今しようとしているように、タイマー値でラベルを更新していました。これをチェックしてください:http://sourceforge.net/projects/mybullsandcows – Juvanis

+0

私は自分の仕事のためにかなり良い仕事をしているようですが、当分の間あなたの文字列の連結に行くことに決めました:)あなたの助けに感謝! – StartingGroovy

1

あなたが指定した数学をしたいと思っていますが、それぞれの価値の底を取ると思います。次に連結します。

public class Test{ 
    public static void main(String args[]){ 
     double d = -100.675; 
     float f = -90;  

     System.out.println(Math.floor(d)); 
     System.out.println(Math.floor(f)); 

     System.out.println(Math.ceil(d)); 
     System.out.println(Math.ceil(f)); 
    } 
} 
+0

すみませんが、それは本当に悪いアドバイスだと思います。正の値を整数で除算すると、丸め誤差のリスクは全くありません。あなたのアプローチについては言えません。 – ruakh

3

SimpleDateFormat()は、あなたのニーズに本当に適しています。

+0

Centinski私は、SimpleDateFormatが好ましい方法であると考えました。応答していただきありがとうございます。私はそれを他のものと同様にテストするつもりです。 – StartingGroovy

+0

あなたの意見をお寄せいただきありがとうございます。答えとあなたの時間を+1してください:) – StartingGroovy

3

hereのようにTimeUnitクラスを使用し、javax.swing.Timerクラスを1秒間隔で実行するように設定します。

+0

私はこの例が好きで、試してみました。にリンクされた例は、余分な閉じ括弧のために構文エラーを持つ可能性があります。それ以外に、この変換はすべてSimpleDateFormatほど効率的ですか? – StartingGroovy

+0

@StartingGroovy、構文エラーに言及してくれてありがとう!そして私はあまりにも確信していません... – Moonbeam

+0

私は 'TimeUnit'を私に見せてくれてありがとうと思っていました。私はこのオプションを選んでいませんでしたが、あなたがそれをやる別の方法を明らかにしてうれしいです!早期最適化に関するアドバイスをいただきありがとうございます – StartingGroovy

5

私があなたの場合はSimpleDateFormatを使用します。

SDFがあなたにとって遅すぎる場合は、すべてのオプションをプロファイルし、最も速いものを選んで、残りのコードを十分に速くなるまでリファクタリングします。

時期尚早の最適化はすべての悪のルートであることを忘れないでください、とあなただけの本当に後に任意の最適化 を行う必要があることを、あなたはがあなたのターゲットの実行時間を逃したあなたのコードをプロファイリングしました。

+0

+1 – asgs

+1

@Chris Browne私は最適化についてのアドバイスも好きです。私は提供された各ソリューションをテストして、どのように行っているかを見ています。 – StartingGroovy

2

値のラッピングを気にしない場合は、次のようにSimpleDateFormatを使用します。ミリ秒に変換し、手動でタイムゾーンを上書きするには、x1000を覚えておいてください。あなたは時間が23.59.59過ぎて行きたい場合は

long value = 5 * 24 * 3600 + 5000; 

// wrapping solution 
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 
// ensure no daylight saving +1 hour 
sdf.setTimeZone(TimeZone.getTimeZone("GMT")); 
System.out.println(sdf.format(value * 1000)); 

出力

01:23:20 

が、これは私が思い付くことができ最も簡単です。 DecimalFormatを使用して、少なくとも2桁の時間を強制しました。

long value = 5 * 24 * 3600 + 5000; 

long hours = value/3600; // whole hours 
long mins = value/60 - hours * 60; 
long secs = value % 60; 
System.out.println(String.format("%s:%2d:%2d", 
     new DecimalFormat("00").format(hours), mins, secs)); 

私は、これは非常に高速であることが判明しまし出力

121:23:20 
+0

2番目の例で追加して嬉しいです。結果は最終的には24時間を超えると確信しています – StartingGroovy

+0

私はちょうどあなたにも感謝したいと思います。ユーザーがソースを例として提供してくれることを感謝します。これは、お互いにメソッドをテストする素晴らしい方法です。あなたの時間をありがとう、アダム – StartingGroovy

2

。やってみて。秒は0〜59、分は0〜59、時間は0〜2,562,047,788,015になります。その後、時間は負になり、その最大値に向かい始めます。

文字列の "+"演算子の実行は非常に遅いです。 StringBuilderは、私が見たものから最も速くグループ化する文字列をまとめて処理します。また、 "String/Byte"ではなく "chars"を使用する必要があります。バイトも非常に遅いです。私は36と6で割ることは、保持するために大きなする小数を与えるだけで乗算を行うことを好むだろう。

StringBuilder sb = new StringBuilder(8); 
    long hours = time/3600000; 
    long minutes = (time - hours * 3600000)/60000; 
    long seconds = (time - hours * 3600000 - minutes * 60000)/1000; 

    if (hours < 10) 
     sb.append('0'); 
    sb.append(hours); 
    sb.append(':'); 

    if (minutes < 10) 
     sb.append('0'); 
    sb.append(minutes); 
    sb.append(':'); 

    if (seconds < 10) 
     sb.append('0'); 
    sb.append(seconds); 

    String formattedTime = sb.toString(); 

.....

関連する問題