私が持っています...
Date start = new Date()
...
...
...
Date stop = new Date()
これら2つの日付の間に、年、月、日、時間、分、秒が経過したものを取得したいと思います。
-
質問を絞り込みます。
うるう年、各月の日などを考慮せずに、絶対的な測定値として経過時間を取得したいだけです。
したがって、年月を経過させることは不可能だと思います。取得できるのは、日、時間、分、秒だけです。
より具体的には、特定のタスクがたとえば.
20 sec
13 min, 4 sec
2 h, 10 min, 2 sec
4 d, 4 h, 2 min, 2 sec
だから、私の精度の欠如を許してください。
この簡単なGroovyソースソリューションを発見しました。
import groovy.time.TimeCategory
import groovy.time.TimeDuration
TimeDuration td = TimeCategory.minus( stop, start )
println td
これはすべて、除算とmodで行えます。
long l1 = start.getTime();
long l2 = stop.getTime();
long diff = l2 - l1;
long secondInMillis = 1000;
long minuteInMillis = secondInMillis * 60;
long hourInMillis = minuteInMillis * 60;
long dayInMillis = hourInMillis * 24;
long elapsedDays = diff / dayInMillis;
diff = diff % dayInMillis;
long elapsedHours = diff / hourInMillis;
diff = diff % hourInMillis;
long elapsedMinutes = diff / minuteInMillis;
diff = diff % minuteInMillis;
long elapsedSeconds = diff / secondInMillis;
これで、要求したすべての情報が得られます。
編集:人々は混乱しているように見えるので、いや、これはうるう年や夏時間の切り替えなどを考慮に入れていません。それは純粋な経過ですtime、opensasが求めたものです。
標準のDate APIではそれほど簡単ではありません。
代わりに Joda Time または JSR-31 をご覧ください。
私はJodaの専門家ではありませんが、コードは次のようになると思います。
Interval interval = new Interval(d1.getTime(), d2.getTime());
Period period = interval.toPeriod();
System.out.printf(
"%d years, %d months, %d days, %d hours, %d minutes, %d seconds%n",
period.getYears(), period.getMonths(), period.getDays(),
period.getHours(), period.getMinutes(), period.getSeconds());
JodaTimeに関しては、私はちょうどそれを始めました。それを提案したレスポンダーに感謝します。 Jodaコードのより凝縮されたバージョンを以下に示します。
Period period = new Period(d1.getTime(), d2.getTime());
System.out.printf(
"%d years, %d months, %d days, %d hours, %d minutes, %d seconds%n",
period.getYears(), period.getMonths(), period.getDays(),
period.getHours(), period.getMinutes(), period.getSeconds());
(これが元の質問に役立つかどうかはわかりませんが、確かに検索者です)。
Duration.between( then , Instant.now() )
最新の方法では、面倒な古い日時クラスに取って代わるJava.timeクラスを使用します。
Date
の代わりに、Instant
を使用します。 Instant
クラスは、 [〜#〜] utc [〜#〜] のタイムライン上の瞬間を ナノ秒 (最大9桁の解像度)で表します小数の)。
Instant then = Instant.now();
…
Instant now = Instant.now();
Duration
クラスを使用して、タイムラインに関連付けられていない期間、day-hours-minutes-seconds-nanosの解像度を使用します。
Duration d = Duration.between( then , now );
年-月-日の解像度を持つ期間については、 Period
クラスを使用します。
文字列の生成は標準です ISO 8601 形式 期間用 :PnYnMnDTnHnMnS
。 P
は開始を示します。 T
は、年、月、日、時間、分、秒を区切ります。したがって、2時間半はPT2H30M
です。
String output = d.toString();
Java9以降では、toDaysPart
、toHoursPart
などのメソッドを使用して個々のパーツにアクセスできます。
また、Java9以降ではInstant.now
が改善され、Javaで見られる ミリ秒 ではなく マイクロ秒 で現在の瞬間をキャプチャします。 8.もちろん、Javaのすべてのバージョンで、Instant
クラスはholdの値を nanoseconds にできます。
Java.time フレームワークはJava8以降に組み込まれています。これらのクラスは、 Java.util.Date
、 Calendar
、& SimpleDateFormat
などの厄介な古い legacy 日時クラスに取って代わります。
Joda-Time プロジェクトは、現在 メンテナンスモード であり、 Java.time クラスへの移行を推奨しています。
詳細については、 Oracleチュートリアル を参照してください。また、Stack Overflowで多くの例と説明を検索してください。仕様は JSR 31 です。
Java.timeクラスはどこで入手できますか?
ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある証明の場です。ここでは、 Interval
、 YearWeek
、 YearQuarter
、および more などの便利なクラスを見つけることができます。
Java 1.5を使用する必要があります TimeUnit。
これは簡単でわかりやすい例です。グルーヴィーでは(いつものように)短くなると思います。
/**
* Formats a given {@link Date} to display a since-then timespan.
* @param created
* @return String with a format like "3 minutes ago"
*/
public static String getElapsedTime(Date created) {
long duration = System.currentTimeMillis() - created.getTime();
long seconds = TimeUnit.MILLISECONDS.toSeconds(duration);
long days = TimeUnit.MILLISECONDS.toDays(duration);
long hours = TimeUnit.MILLISECONDS.toHours(duration);
long minutes = TimeUnit.MILLISECONDS.toMinutes(duration);
if (days > 0) {
return days + " days";
}
if (hours > 0) {
return hours + " hrs";
}
if (minutes > 0) {
return minutes + " minutes";
}
return seconds + " seconds";
}
ああ、複数のリターンを避けてください;)
実際、 Joda-Time についての上記の回答に関して。
Joda-Timeの Period クラスでこれを行う簡単な方法があります。
Period period = new Period(startDate, endDate);
System.out.println(PeriodFormat.getDefault().print(period));
出力をカスタマイズするには、 PeriodFormat 、 PeriodFormatter 、および PeriodFormatterBuilder クラスを調べます。
前述の素晴らしい JodaTime APIとは別に、私doが推奨するAPI、最高の標準Java代わりに Java.util.Calendar
を使用することもできますcumbersomeを使用する(これは控えめな表現です..行JodaTimeの例)、ただし経過時間も計算できます重要なキーは、ループでCalendar#add()
を使用して、うるう日を取るために年、月、日の経過値を取得することです、年、世紀を考慮します(ミリ秒)から計算してはなりません。
基本的な例を次に示します。
import Java.util.Calendar;
public class Test {
public static void main(String[] args) throws Exception {
Calendar start = Calendar.getInstance();
start.set(1978, 2, 26, 12, 35, 0); // Just an example.
Calendar end = Calendar.getInstance();
Integer[] elapsed = new Integer[6];
Calendar clone = (Calendar) start.clone(); // Otherwise changes are been reflected.
elapsed[0] = elapsed(clone, end, Calendar.YEAR);
clone.add(Calendar.YEAR, elapsed[0]);
elapsed[1] = elapsed(clone, end, Calendar.MONTH);
clone.add(Calendar.MONTH, elapsed[1]);
elapsed[2] = elapsed(clone, end, Calendar.DATE);
clone.add(Calendar.DATE, elapsed[2]);
elapsed[3] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 3600000;
clone.add(Calendar.HOUR, elapsed[3]);
elapsed[4] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 60000;
clone.add(Calendar.MINUTE, elapsed[4]);
elapsed[5] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 1000;
System.out.format("%d years, %d months, %d days, %d hours, %d minutes, %d seconds", elapsed);
}
private static int elapsed(Calendar before, Calendar after, int field) {
Calendar clone = (Calendar) before.clone(); // Otherwise changes are been reflected.
int elapsed = -1;
while (!clone.after(after)) {
clone.add(field, 1);
elapsed++;
}
return elapsed;
}
}
現在の私の年齢を表示する必要があります=)
Calendar#setTime()
を使用して、Date
をCalendar
に「変換」できます。
うーん、もし私があなたが求めているものを手に入れたら、あなたはそれを知りたい:
start = 2001年1月1日、午前10:00:00.000および
stop = 2003年1月6日、午後12:01:00.000 pm
2年、0か月、5日、2時間、1分の回答が必要な場合
残念ながら、これは正解です。日付が1月2日と1月31日だった場合はどうなりますか?それは29日でしょうか?わかりましたが、2月2日から3月2日は28(29)日ですが、1か月と表示されますか?
月と年は長さが異なるため、秒または場合によっては日以外の時間の長さは、コンテキストを知らなくても可変です。 2つの日付の差は静的な単位である必要があります。これは、stop.getTime()-start.getTime()(ミリ秒単位の差)から簡単に計算できます
私はこれを一般的に行います:
def start_time = System.currentTimeMillis()
...
def end_time = System.currentTimeMillis()
println (end_time - start_time) +' ms'
その後、Duration Groovyクラスを使用して、任意の時間単位に分割できます http://docs.groovy-lang.org/latest/html/api/groovy/time/Duration.html 。
それは簡単です;適切なタイムゾーンを設定する必要があります
import Java.util.TimeZone;
import Java.util.logging.Logger;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class ImportData {
private final static Logger log = Logger.getLogger(ImportData.class.getName());
private final static DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS");
private final static DateTimeFormatter dtfh = DateTimeFormat.forPattern("HH:mm:ss.SSS");
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"));
DateTimeZone.setDefault(DateTimeZone.forID("Europe/Berlin"));
// Quotes connection=Quotes.getInstance();
final long start = System.currentTimeMillis();
// do something here ...
// connection.importTickdata();
Thread.currentThread().sleep(2000);
final long end = System.currentTimeMillis();
log.info("[start] " + dtf.print(start));
log.info("[end] " + dtf.print(end));
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
DateTimeZone.setDefault(DateTimeZone.forID("UTC"));
log.info("[duration] " + dtfh.print(end - start));
// connection.logOff();
// System.exit(0);
}
戻り値:
10.11.2010 00:08:12 ImportData main INFO:[start] 2010-11-10 00:08:10.306 10.11.2010 00:08:12 ImportData main INFO:[end] 2010-11-10 00:08:12.318 10.11.2010 00:08:12 ImportData main INFO:[duration] 00:00:02.012
これは別の同様の機能です。必要ない場合はリテラルを変更しなければ、日、時間、分などは表示されません。
public class ElapsedTime {
public static void main(String args[]) {
long start = System.currentTimeMillis();
start -= (24 * 60 * 60 * 1000 * 2);
start -= (60 * 60 * 1000 * 2);
start -= (60 * 1000 * 3);
start -= (1000 * 55);
start -= 666;
long end = System.currentTimeMillis();
System.out.println(elapsedTime(start, end));
}
public static String elapsedTime(long start, long end) {
String auxRet = "";
long aux = end - start;
long days = 0, hours = 0, minutes = 0, seconds = 0, milliseconds = 0;
// days
if (aux > 24 * 60 * 60 * 1000) {
days = aux / (24 * 60 * 60 * 1000);
}
aux = aux % (24 * 60 * 60 * 1000);
// hours
if (aux > 60 * 60 * 1000) {
hours = aux / (60 * 60 * 1000);
}
aux = aux % (60 * 60 * 1000);
// minutes
if (aux > 60 * 1000) {
minutes = aux / (60 * 1000);
}
aux = aux % (60 * 1000);
// seconds
if (aux > 1000) {
seconds = aux / (1000);
}
milliseconds = aux % 1000;
if (days > 0) {
auxRet = days + " days ";
}
if (days != 0 || hours > 0) {
auxRet += hours + " hours ";
}
if (days != 0 || hours != 0 || minutes > 0) {
auxRet += minutes + " minutes ";
}
if (days != 0 || hours != 0 || minutes != 0 || seconds > 0) {
auxRet += seconds + " seconds ";
}
auxRet += milliseconds + " milliseconds ";
return auxRet;
}
}
これは、Sebastian Celis answerに基づいて実装した完全な関数です。そして再び、彼の投稿から-これはうるう年や夏時間の切り替えなどを考慮していません。純粋な経過時間です。
出力は私のニーズに合わせて調整されています。これは、3つの重要なセクションのみを出力します。返す代わりに
4ヶ月、2週間、3日、7時間、28分、43秒
最初の3ブロックを返すだけです(投稿の最後に実行されるサンプルを参照してください):
4ヶ月、2週間、3日
メソッドの完全なソースコードを次に示します。
/**
* Format milliseconds to elapsed time format
*
* @param time difference in milliseconds
* @return Human readable string representation - eg. 2 days, 14 hours, 5 minutes
*/
public static String formatTimeElapsedSinceMillisecond(long milisDiff) {
if(milisDiff<1000){ return "0 second";}
String formattedTime = "";
long secondInMillis = 1000;
long minuteInMillis = secondInMillis * 60;
long hourInMillis = minuteInMillis * 60;
long dayInMillis = hourInMillis * 24;
long weekInMillis = dayInMillis * 7;
long monthInMillis = dayInMillis * 30;
int timeElapsed[] = new int[6];
// Define time units - plural cases are handled inside loop
String timeElapsedText[] = {"second", "minute", "hour", "day", "week", "month"};
timeElapsed[5] = (int) (milisDiff / monthInMillis); // months
milisDiff = milisDiff % monthInMillis;
timeElapsed[4] = (int) (milisDiff / weekInMillis); // weeks
milisDiff = milisDiff % weekInMillis;
timeElapsed[3] = (int) (milisDiff / dayInMillis); // days
milisDiff = milisDiff % dayInMillis;
timeElapsed[2] = (int) (milisDiff / hourInMillis); // hours
milisDiff = milisDiff % hourInMillis;
timeElapsed[1] = (int) (milisDiff / minuteInMillis); // minutes
milisDiff = milisDiff % minuteInMillis;
timeElapsed[0] = (int) (milisDiff / secondInMillis); // seconds
// Only adds 3 significant high valued units
for(int i=(timeElapsed.length-1), j=0; i>=0 && j<3; i--){
// loop from high to low time unit
if(timeElapsed[i] > 0){
formattedTime += ((j>0)? ", " :"")
+ timeElapsed[i]
+ " " + timeElapsedText[i]
+ ( (timeElapsed[i]>1)? "s" : "" );
++j;
}
} // end for - build string
return formattedTime;
} // end of formatTimeElapsedSinceMillisecond utility method
サンプルテストステートメントの例を次に示します。
System.out.println(formatTimeElapsedSinceMillisecond(21432424234L));
// Output: 8 months, 1 week, 1 day
System.out.println(formatTimeElapsedSinceMillisecond(87724294L));
// Output: 1 day, 22 minutes, 4 seconds
System.out.println(formatTimeElapsedSinceMillisecond(123434L));
// Output: 2 minutes, 3 seconds
import groovy.time.TimeCategory
import groovy.time.TimeDuration
time = { closure ->
use(TimeCategory) {
def started = new Date()
def res = closure()
TimeDuration duration = new Date() - started
logger.info("Execution duration: " + duration.toMilliseconds() + "ms")
res
}
}
time {
println 'A realy heavy operation here that you want to measure haha'
}
Dateオブジェクトを作成しても、System.currentTimeMillis()をラップするだけなので意味はありません。 getTime()関数は、Dateオブジェクトをラップ解除するだけです。この関数を使用してlongを取得することをお勧めします。
2番目の精度のみが必要な場合は、これで問題ありません。ただし、サブミリ秒の精度が必要な場合は、System.nanoTime()を使用して経過時間を取得します。