web-dev-qa-db-ja.com

Java:文字列(HH:MM:SS)を期間に変換する方法は?

hH:MM:SSまたはMM:SSまたはSSの形式の文字列を期間のデータ型に変換したい。

解決:

    private ArrayList<Duration> myCdDuration = new ArrayList<Duration>();

        private void convert(String aDuration) {

            chooseNewDuration(stringToInt(splitDuration(aDuration))); //stringToInt() returns an int[] and splitDuration() returns a String[]
        }

        private void chooseNewDuration(int[] array) {
            int elements = array.length;
            switch (elements) {
            case 1:
                myCdDuration.add(newDuration(true, 0, 0, 0, 0, 0, array[0]));
                break;
            case 2:
                myCdDuration.add(newDuration(true, 0, 0, 0, 0, array[0], array[1]));
                break;
            case 3:
                myCdDuration.add(newDuration(true, 0, 0, 0, array[0], array[1],
                        array[2]));
                break;
            }
        }

助けてくれてありがとう...それを行う簡単な方法は? ->独自の期間クラスを作成します。

public class Duration {
        private int intSongDuration;
        private String printSongDuration;

        public String getPrintSongDuration() {
            return printSongDuration;
        }

        public void setPrintSongDuration(int songDuration) {
            printSongDuration = intToStringDuration(songDuration);
        }

        public int getIntSongDuration() {
            return intSongDuration;
        }

        public void setIntSongDuration(int songDuration) {
            intSongDuration = songDuration;
        }

        public Duration(int songDuration) {

            setIntSongDuration(songDuration);
        }

出力/印刷用にint値を文字列に変換します。

private String intToStringDuration(int aDuration) {
    String result = "";

    int hours = 0, minutes = 0, seconds = 0;

    hours = aDuration / 3600;
    minutes = (aDuration - hours * 3600) / 60;
    seconds = (aDuration - (hours * 3600 + minutes * 60));

    result = String.format("%02d:%02d:%02d", hours, minutes, seconds);
    return result;
}
18
Frank
  1. あなたのmyCdDurationは混乱しています。 oneDurationオブジェクトは、文字列で指定されたものと同じですか、それともDurationオブジェクトのリストですか。最初は時間、2番目の分などが含まれていますか?

  2. Stringを他のオブジェクトにキャストすることはできません。値を解析して数値型に変換し、 DataTypeFactory を使用してDurationオブジェクトを構築する必要があります。

2
andri

私が最終的に達成しようとしているのは、CDの継続時間を秒単位で計算することだと思います。

これにはいくつかの方法がありますが、最も簡単なのは、:で分割して時間、分、秒のフィールドを取得し、手動で期間を計算することです。

String timestampStr = "14:35:06";
String[] tokens = timestampStr.split(":");
int hours = Integer.parseInt(tokens[0]);
int minutes = Integer.parseInt(tokens[1]);
int seconds = Integer.parseInt(tokens[2]);
int duration = 3600 * hours + 60 * minutes + seconds;
19

tl; dr

Javaが提供するため、独自のDurationクラスを定義する必要はありません。

Duration.between (                  // Represent a span of time of hours, minutes, seconds. 
    LocalTime.MIN ,                 // 00:00:00
    LocalTime.parse ( "08:30:00" )  // Parse text as a time-of-day. 
)                                   // Returns a `Duration` object, a span-of-time. 
.toString()                         // Generate a `String` with text in standard ISO 8601 format. 

PT8H30M

また、標準のISO 8601形式のテキストを解析します。

Duration.parse( "PT8H30M" )   // Parse standard ISO 8601 text yo get a `Duration` object. 

HH:MM:SS形式を使用しない

文字列08:30:00によって、時刻の「朝の8時半」ではなく、「8時間半」の時間を意味する場合、HH:MM:SSの形式は避けてください。その形式はあいまいで、時刻のように見えます。代わりに、以下で説明する標準のISO 8601形式を使用してください。

期間と時刻は、2つの非常に異なる概念です。あなたはそれらについて明確でなければなりません、それぞれがあなたの心の中で異なっているべきです。 HH:MM:SSのあいまいな形式を使用すると、その区別がさらに難しくなります(そのため、その形式は避けてください!)。

Java.time

最新の方法は、Java.timeクラスを使用する方法です。

LocalTime

まず、文字列を LocalTime として解析します。このクラスは、日付とタイムゾーンなしの時刻を表します。タイムゾーンがないことは、これらのオブジェクトが 夏時間(DST) などの異常に関係なく、一般的な24時間時計に基づいていることを意味します。

入力文字列は時刻ではなく時間の範囲を表すため、LocalTimeは実際には必要ありません。しかし、これは最初のステップにすぎません。

LocalTime lt = LocalTime.parse ( "08:30:00" );

Duration

希望する期間を表すには、 Duration クラスが必要です。このクラスは、タイムラインに関連付けられていない期間用です。時刻クロックの開始からの時間量、00:00:00.0または LocalTime.MIN を取得してLocalTimeを変換し、ltを変換することで作成できます。インスタンス化。

Duration d = Duration.between ( LocalTime.MIN , lt );

入力文字列を編集する

上記のLocalTimeを使用するアプローチは、入力文字列が24時間未満の期間を表す場合にのみ機能します。 24時間を超える場合は、入力文字列を自分で解析します。

次のコードのようなもの。もちろん、実際の解析は、特定の入力文字列のあいまいさを解決することに依存しています。 50:00は50時間または50分ですか? (このあいまいさは、この紛らわしいフォーマットを可能な限り避け、ISO 8601フォーマットに固執する強い理由です。)

String input = "50:00";  // Or "50:00:00" (fifty hours, either way)

String[] parts = input.split ( ":" );
Duration d = Duration.ZERO;
if ( parts.length == 3 ) {
    int hours = Integer.parseInt ( parts[ 0 ] );
    int minutes = Integer.parseInt ( parts[ 1 ] );
    int seconds = Integer.parseInt ( parts[ 2 ] );
    d = d.plusHours ( hours ).plusMinutes ( minutes ).plusSeconds ( seconds );
} else if ( parts.length == 2 ) {
    int hours = Integer.parseInt ( parts[ 0 ] );
    int minutes = Integer.parseInt ( parts[ 1 ] );
    d = d.plusHours ( hours ).plusMinutes ( minutes );
} else {
    System.out.println ( "ERROR - Unexpected input." );
}

ISO 8601

標準の 期間のISO 8601形式 で文字列を生成するだけで結果を確認できます Duration::toString を呼び出すだけです。 Java.timeクラスは、文字列の解析/生成時にデフォルトでISO 8601を使用します。期間の場合、標準形式はPnYnMnDTnHnMnSです。ここで、Pは開始を示し、Tは、年、月、日の部分と時間、分、秒の部分を区切ります。したがって、8時間半はPT8H30Mと表示されます。

System.out.println( "d.toString():" + d);

d.toString():PT8H30M

Durationオブジェクトの収集

List型の要素を保持するDurationを作成できます。

List<Duration> durations = new ArrayList<>( 3 );  // Initial capacity of 3 elements.
durations.add( d ) ;
durations.add( Duration.between ( LocalTime.MIN , LocalTime.parse ( "03:00:00" ) ) ) ;
durations.add( Duration.between ( LocalTime.MIN , LocalTime.parse ( "01:15:00" ) ) ) ;

durations.toString():[PT8H30M、PT3H、PT1H15M]

PT8H30Mのような出力に表示される文字列は、生成された文字列の出力です。 Durationタイプは単純な文字列ではなくですが、 toString メソッドによって文字列オブジェクトを生成します。

ISO 8601形式を使用する場合、そのような文字列を簡単に解析および生成できます。この回答の冒頭で実行したLocalTime変換リガマロールを実行する必要はありません。

Duration d = Duration.parse( "PT8H30M" );

この例を参照してください コードはIdeOne.comでライブ


Java.timeについて

Java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、面倒な古い legacy などの日時クラスに取って代わります- Java.util.DateCalendar 、& SimpleDateFormat

Joda-Time プロジェクトは現在 maintenance mode であり、 Java.time クラスへの移行を推奨しています。

詳細については、 Oracleチュートリアル を参照してください。また、スタックオーバーフローで多くの例と説明を検索してください。仕様は JSR 31 です。

Java.timeクラスはどこで入手できますか?

ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明する場です。 IntervalYearWeekYearQuarter 、および more などの便利なクラスがここにあります。

18
Basil Bourque

Utilsクラスにこのメソッドを記述して、さまざまな種類の期間文字列を解析しました。それは非常に柔軟です:

public static int getSecondsFromFormattedDuration(String duration){
        if(duration==null)
            return 0;
        try{

            Pattern patternDuration = Pattern.compile("\\d+(?::\\d+){0,2}");

            int hours = 0;
            int minutes = 0;
            int seconds = 0;
            if(patternDuration.matcher(duration).matches()){
                String[] tokens = duration.split(":");
                if(tokens.length==1){
                    seconds = Integer.parseInt(tokens[0]);
                }else if(tokens.length == 2){
                    minutes = Integer.parseInt(tokens[0]);
                    seconds = Integer.parseInt(tokens[1]);
                }else{
                    hours = Integer.parseInt(tokens[0]);
                    minutes = Integer.parseInt(tokens[1]);
                    seconds = Integer.parseInt(tokens[2]);
                }

                return 3600 * hours + 60 * minutes + seconds;
            }else
                return 0;

        }catch (NumberFormatException ignored){
            return 0;
        }

}

これは、これらの期間を解析した方法です。

"1"   -->  1
"10"  -->  10
"10:"   -->  0  (not a valid duration)
"10:07"   -->  607
"06:08"   -->  368
"7:22"   -->  442
":22"   -->  0  (not a valid duration)
"10:32:33"   -->  37953
"2:33:22"   -->  9202
"2:2:02"   -->  7322
"2:33:43:32"   -->  0  (not a valid duration)
"33ff"   -->  0  (not a valid duration)
"2d:33"   -->  0  (not a valid duration)
2
Rahul Verma

私はjavax.xml.datatype.Durationを使用してしないことをお勧めします。これは、XMLに関連するJava APIであり、 XMLを扱っていない場合に使用します。さらに、それは抽象クラスであり、Java SEに、抽象化されていないドキュメント化された実装がないため、次のいずれかを作成する必要があります。非抽象実装を所有するか、何らかの方法でインスタンスを取得します(おそらく、XML APIで遊んでいます)。

DateおよびCalendarクラスを使用して、Java=で時刻と日付を管理します。StringsをDate/Calendarに変換するには、DateFormatまたはSimpleDateFormatを使用します。これにより、100%ではありませんが、期間の計算を実行できます可愛い。

Mansoorは、文字列操作を使用して手動で処理を行い、期間を数値として処理する方法を提供します。単純な処理のみを実行する場合は、それを行う方が簡単です。

より複雑なことを実行する必要がある場合は、 http://joda-time.sourceforge.net/ を調べてください。

1
alex

Java 8およびJava.time.Durationを使用すると、文字列の形式がHH:MM:SSまたはMM:SSまたはSSであれば、これを行うことができます

Duration.ofSeconds(Arrays.stream(runtime.split(":"))
                  .mapToInt(n -> Integer.parseInt(n))
                  .reduce(0, (n, m) -> n * 60 + m));
0
Asthor

サンプル、現在の日時を期間に変換Java 7。

DatatypeFactory.newInstance().newDuration(Calendar.getInstance().getTimeInMillis())

出力-

P48Y5M13DT19H59M24.658S

0
Ajay Kumar