2012-03-12 32 views
1

我想要我的JLabel顯示值的格式爲HH:mm:ss而不使用任何外部庫。 (該標籤將每秒更新一次)將長轉換爲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 



我知道,一般人會只是做以下轉換以獲得所需的數字:

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 2012-03-12 19:58:53

+1

回覆:「然而,這會在值上留下小數」:我不知道你的意思。在Java中,如果's'是'long',那麼's/3600'很長;它執行[整數除法](http://mathworld.wolfram.com/IntegerDivision.html),所以不會產生小數點。 – ruakh 2012-03-12 20:00:34

+0

@ruakh我可能需要在中添加天數類別,但我還沒有遇到它。我只知道我將來會遇到它。現在我只想確保我能夠適當地顯示小時,分鐘和秒鐘。另外就長期而言,我在Groovy而不是Java中簡單地測試過它,也許它轉換了類型,但我不知道它是爲什麼顯示小數。 (我沒有意識到,直到你指出) – StartingGroovy 2012-03-12 20:27:52

回答

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 2012-03-12 21:11:43

+0

@StartingGroovy曾幾何時,我使用這種方法來實現遊戲,我正在用定時器值更新一個標籤,就像你現在要做的那樣。檢查此:http://sourceforge.net/projects/mybullsandcows – Juvanis 2012-03-12 21:20:35

+0

我已決定暫時與您的字符串連接,因爲它似乎做了我的任務在手頭很好:)謝謝你的幫助! – StartingGroovy 2012-03-13 14:59:00

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 2012-03-12 20:01:57

3

SimpleDateFormat()真的非常適合您的需求。

+0

Centinski我認爲SimpleDateFormat應該是首選的方法。感謝您的迴應。我要測試它以及其他人。 – StartingGroovy 2012-03-12 21:15:00

+0

感謝您提供您的意見,+1的答案和你的時間:) – StartingGroovy 2012-03-13 15:00:49

3

使用TimeUnit類,如here結合javax.swing.Timer類設置爲以1秒爲間隔執行。

+0

我喜歡這個例子,並試了一下。鏈接到的示例可能由於附加的圓括號而導致語法錯誤。除此之外,所有這些轉換都將像SimpleDateFormat一樣高效嗎? – StartingGroovy 2012-03-12 20:49:22

+0

@StartingGroovy,謝謝你提到的語法錯誤!我不太確定... – Moonbeam 2012-03-12 22:42:51

+0

我想感謝你給我看'TimeUnit'。雖然我沒有選擇這個選項,但我很高興你透露了另一種方式!感謝您的時間 – StartingGroovy 2012-03-13 15:00:02

5

如果我是你,我會使用SimpleDateFormat。

如果SDF對您來說太慢,請勾選您的所有選項並選擇最快的選項,然後重構代碼的其餘部分,直到速度足夠快。

記住過早的優化是一切罪惡的根源,那你應該只有真正做任何優化後你異形代碼錯過了你的目標執行時間。

+0

+1對於過早優化的建議。 – asgs 2012-03-12 20:09:32

+1

@Chris Browne我也喜歡關於優化的建議。我正在測試每個提供的解決方案並查看它們的具體情況 – StartingGroovy 2012-03-12 21:12:56

2

如果你不介意值包裝,然後使用SimpleDateFormat如下。記住x1000將轉換爲毫秒並手動覆蓋時區。

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 

如果你想的時間去過去23.59.59那麼這是我能想出的最簡單的。我使用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

我很高興你在第二個例子中添加了,並提供了輸出結果,因爲最終我確定時間將超過24小時 – StartingGroovy 2012-03-12 22:27:22

+0

我只是想感謝你。我很欣賞用戶提供源代碼的例子。這是測試彼此對抗的好方法。謝謝你的時間亞當 – StartingGroovy 2012-03-13 15:04:47

2

我發現這是非常快的。試試看。秒數從0到59,分鐘從0到59,小時從0到2562,047,788,015。之後,小時數變爲負值,並開始向最大值發展。

在Strings上執行「+」運算符非常慢。一個StringBuilder執行從我所見過的最快的字符串分組。你也應該使用「字符」而不是「字符串/字節」字節也很慢。我寧願只進行乘法運算,但除以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(); 

.....

相關問題