System.currentTimeMillis()
사용자가 프로그램에서 무언가를 시작할 때 사용하는 시간을 기록하고 싶습니다 . 완료되면 변수 에서 전류 System.currentTimeMillis()
를 빼고 start
"XX 시간, XX 분, XX 초"또는 "XX 분, XX 초"와 같은 사람이 읽을 수있는 형식을 사용하여 경과 된 시간을 보여주고 싶습니다. 한 시간 동안 누군가를 데려 가지 않을 것입니다.
가장 좋은 방법은 무엇입니까?
System.currentTimeMillis()
사용자가 프로그램에서 무언가를 시작할 때 사용하는 시간을 기록하고 싶습니다 . 완료되면 변수 에서 전류 System.currentTimeMillis()
를 빼고 start
"XX 시간, XX 분, XX 초"또는 "XX 분, XX 초"와 같은 사람이 읽을 수있는 형식을 사용하여 경과 된 시간을 보여주고 싶습니다. 한 시간 동안 누군가를 데려 가지 않을 것입니다.
가장 좋은 방법은 무엇입니까?
답변:
java.util.concurrent.TimeUnit
수업 사용 :
String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(millis),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);
참고 : TimeUnit
Java 1.5 사양의 일부이지만 toMinutes
Java 1.6부터 추가되었습니다.
값 0-9에 선행 0을 추가하려면 다음을 수행하십시오.
String.format("%02d min, %02d sec",
TimeUnit.MILLISECONDS.toMinutes(millis),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);
지원되지 TimeUnit
않거나 toMinutes
지원되지 않는 경우 (예 : API 버전 9 이전의 Android에서) 다음 방정식을 사용하십시오.
int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours = (int) ((milliseconds / (1000*60*60)) % 24);
//etc...
int hours = (int) ((milliseconds / (1000*60*60)) % 24)
이 작동하지 않습니다! 대신 다음과 같이되어야합니다int hours = (int) (milliseconds / (1000*60*60)) ;
String.format("%01d:%02d:%02d", hours, minutes, seconds);
@siddhadev의 답변에 따라 밀리 초를 형식이 지정된 문자열로 변환하는 함수를 작성했습니다.
/**
* Convert a millisecond duration to a string format
*
* @param millis A duration to convert to a string form
* @return A string of the form "X Days Y Hours Z Minutes A Seconds".
*/
public static String getDurationBreakdown(long millis) {
if(millis < 0) {
throw new IllegalArgumentException("Duration must be greater than zero!");
}
long days = TimeUnit.MILLISECONDS.toDays(millis);
millis -= TimeUnit.DAYS.toMillis(days);
long hours = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
StringBuilder sb = new StringBuilder(64);
sb.append(days);
sb.append(" Days ");
sb.append(hours);
sb.append(" Hours ");
sb.append(minutes);
sb.append(" Minutes ");
sb.append(seconds);
sb.append(" Seconds");
return(sb.toString());
}
1 Days 1 Hours 1 Minutes 1 Seconds
long days = TimeUnit.MILLISECONDS.toDays(millis);
long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24;
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60;
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60;
long milliseconds = millis % 1000;
또한 String.format 메소드 :return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds", days, hours, minutes, seconds, milliseconds);
long time = 1536259;
return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time));
인쇄물:
25 : 36 : 259
Duration dur = new Duration(start, end);
long millis = dur.getMillis();
DateTimeFormat.forPattern("mm:ss:SSS").print(new DateTime(time));
또는 지속 시간을 Joda를 사용하여 자동으로 인쇄 할 수있는 기간으로 변환하십시오 PeriodFormatter
. ISO 연대기가 아닌 경우 변환의 정밀도가 떨어질 수 있습니다. 변수가 나타내는 Duration을 가정합니다 duration
. Period period = duration.toPeriod().normalizedStandard(PeriodType.time());
PeriodFormat.getDefault().print(period))
출력은 굉장합니다 : 1 초와 581 밀리 초로 위의 주요 질문에 대답하십시오.
음 ... 1 초에 몇 밀리 초입니까? 그리고 잠시 후에? 사단은 그렇게 어렵지 않습니다.
int seconds = (int) ((milliseconds / 1000) % 60);
int minutes = (int) ((milliseconds / 1000) / 60);
시간, 일, 주, 월, 년, 수십 년 동안 계속하십시오.
Java 8에서 java.time 패키지 사용 :
Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));
출력에 ISO 8601 시간 형식 : PT1M3.553S
(1 분 3.553 초).
나는 그것을 위해 여분의 의존성을 끌어 들이지 않을 것입니다 (결국 전혀 어렵지 않습니다). 그러나 Commons Lang을 사용하고 있다면 DurationFormatUtils가 있습니다. 있습니다.
사용 예 ( 여기 에서 적응 ) :
import org.apache.commons.lang3.time.DurationFormatUtils
public String getAge(long value) {
long currentTime = System.currentTimeMillis();
long age = currentTime - value;
String ageString = DurationFormatUtils.formatDuration(age, "d") + "d";
if ("0d".equals(ageString)) {
ageString = DurationFormatUtils.formatDuration(age, "H") + "h";
if ("0h".equals(ageString)) {
ageString = DurationFormatUtils.formatDuration(age, "m") + "m";
if ("0m".equals(ageString)) {
ageString = DurationFormatUtils.formatDuration(age, "s") + "s";
if ("0s".equals(ageString)) {
ageString = age + "ms";
}
}
}
}
return ageString;
}
예:
long lastTime = System.currentTimeMillis() - 2000;
System.out.println("Elapsed time: " + getAge(lastTime));
//Output: 2s
참고 : 두 개의 LocalDateTime 객체에서 밀리를 얻으려면 다음을 사용할 수 있습니다.
long age = ChronoUnit.MILLIS.between(initTime, LocalDateTime.now())
손으로 나누거나 SimpleDateFormat API를 사용하십시오 .
long start = System.currentTimeMillis();
// do your work...
long elapsed = System.currentTimeMillis() - start;
DateFormat df = new SimpleDateFormat("HH 'hours', mm 'mins,' ss 'seconds'");
df.setTimeZone(TimeZone.getTimeZone("GMT+0"));
System.out.println(df.format(new Date(elapsed)));
Bombe에 의해 편집 :이 접근법은 작은 기간 (즉, 하루 미만) 동안 만 작동한다는 의견에 표시되었습니다.
HH : mm : ss와 같은 형식을 지정하려면 더 많은 정보를 추가하십시오.
0 <= HH <= 무한
0 <= mm <60
0 <= ss <60
이것을 사용하십시오 :
int h = (int) ((startTimeInMillis / 1000) / 3600);
int m = (int) (((startTimeInMillis / 1000) / 60) % 60);
int s = (int) ((startTimeInMillis / 1000) % 60);
방금이 문제가 있었고 이것을 알아 냈습니다.
최단 솔루션 :
시간대를 다루는 최단 시간 일 것입니다.
System.out.printf("%tT", millis-TimeZone.getDefault().getRawOffset());
예를 들어 다음과 같은 출력이 있습니다.
00:18:32
설명:
%tT
24 시간제 형식의 시간은 %tH:%tM:%tS
입니다.
%tT
또한 long을 입력으로 허용하므로을 만들 필요가 없습니다 Date
.printf()
는 단순히 밀리 초 단위로 지정된 시간을 인쇄하지만 현재 시간대에서는 현재 시간대의 원시 시간 오프셋을 빼야 0 밀리 초가 현재 시간대의 시간 오프셋 값이 아닌 0 시간이됩니다.
참고 # 1 :로 결과가 필요한 경우 다음 String
과 같이 얻을 수 있습니다.
String t = String.format("%tT", millis-TimeZone.getDefault().getRawOffset());
참고 # 2 :millis
일 부분이 출력에 포함되지 않기 때문에 하루 미만인 경우에만 올바른 결과를 제공합니다 .
long millis = 8398;
그리고 그것을 String.format("%tT", millis)
내 출력에 전달하면 19:00:08입니다. 19는 어디에서 왔습니까?
TimeZone.getDefault().getRawOffset()
답에 쓰여진대로 정확히 빼야 합니다.String.format("%tT", millis-TimeZone.getDefault().getRawOffset())
사용 Joda-시간 :
DateTime startTime = new DateTime();
// do something
DateTime endTime = new DateTime();
Duration duration = new Duration(startTime, endTime);
Period period = duration.toPeriod().normalizedStandard(PeriodType.time());
System.out.println(PeriodFormat.getDefault().print(period));
@ brent-nash 컨트 리뷰 션을 다시 방문하면 빼기 대신 모듈러스 함수를 사용하고 결과 문자열에 String.format 메소드를 사용할 수 있습니다.
/**
* Convert a millisecond duration to a string format
*
* @param millis A duration to convert to a string form
* @return A string of the form "X Days Y Hours Z Minutes A Seconds B Milliseconds".
*/
public static String getDurationBreakdown(long millis) {
if (millis < 0) {
throw new IllegalArgumentException("Duration must be greater than zero!");
}
long days = TimeUnit.MILLISECONDS.toDays(millis);
long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24;
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60;
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60;
long milliseconds = millis % 1000;
return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds",
days, hours, minutes, seconds, milliseconds);
}
짧은 시간 동안, 1 시간 미만인 것을 선호합니다 :
long millis = ...
System.out.printf("%1$TM:%1$TS", millis);
// or
String str = String.format("%1$TM:%1$TS", millis);
더 긴 간격 :
private static final long HOUR = TimeUnit.HOURS.toMillis(1);
...
if (millis < HOUR) {
System.out.printf("%1$TM:%1$TS%n", millis);
} else {
System.out.printf("%d:%2$TM:%2$TS%n", millis / HOUR, millis % HOUR);
}
%tH
까지만 보여줍니다. 즉, 예를 들어 24 시간은 00
, 25 시간으로 표시 되고 01
... 일 동안 유효한 동일한 %tT
날짜는 자동으로 삭제됩니다. 물론, 또한 일을 표시 할 수 있지만 내가 (다시 2011 년)이 쓴 내가 가진 문제에 대한 잔인한 [:-) 것
내 간단한 계산 :
String millisecToTime(int millisec) {
int sec = millisec/1000;
int second = sec % 60;
int minute = sec / 60;
if (minute >= 60) {
int hour = minute / 60;
minute %= 60;
return hour + ":" + (minute < 10 ? "0" + minute : minute) + ":" + (second < 10 ? "0" + second : second);
}
return minute + ":" + (second < 10 ? "0" + second : second);
}
행복한 코딩 :)
다음은 Brent Nash 답변, 희망이 도움이되는 답변입니다!
public static String getDurationBreakdown(long millis)
{
String[] units = {" Days ", " Hours ", " Minutes ", " Seconds "};
Long[] values = new Long[units.length];
if(millis < 0)
{
throw new IllegalArgumentException("Duration must be greater than zero!");
}
values[0] = TimeUnit.MILLISECONDS.toDays(millis);
millis -= TimeUnit.DAYS.toMillis(values[0]);
values[1] = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(values[1]);
values[2] = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(values[2]);
values[3] = TimeUnit.MILLISECONDS.toSeconds(millis);
StringBuilder sb = new StringBuilder(64);
boolean startPrinting = false;
for(int i = 0; i < units.length; i++){
if( !startPrinting && values[i] != 0)
startPrinting = true;
if(startPrinting){
sb.append(values[i]);
sb.append(units[i]);
}
}
return(sb.toString());
}
long startTime = System.currentTimeMillis();
// do your work...
long endTime=System.currentTimeMillis();
long diff=endTime-startTime;
long hours=TimeUnit.MILLISECONDS.toHours(diff);
diff=diff-(hours*60*60*1000);
long min=TimeUnit.MILLISECONDS.toMinutes(diff);
diff=diff-(min*60*1000);
long seconds=TimeUnit.MILLISECONDS.toSeconds(diff);
//hour, min and seconds variables contains the time elapsed on your work
diff=diff-(hours*60*1000);
이어야합니다 diff=diff-(hours*60*60*1000);
. 편집을 시도했지만 StackOverflow의 성가신 편집 정책에 따르면 편집 할 문자가 충분하지 않습니다.
첫째로, System.currentTimeMillis()
그리고 Instant.now()
타이밍에 적합하지 않습니다. 둘 다 벽시계 시간을보고합니다.이 시간은 컴퓨터가 정확히 알지 못하며 NTP 데몬이 시스템 시간을 수정하는 경우 뒤로 이동하는 것을 포함하여 잘못 이동할 수 있습니다 . 단일 컴퓨터에서 타이밍이 발생하면 System.nanoTime ()을 대신 사용해야합니다. 합니다.
둘째, Java 8부터 java.time.Duration 이 지속 시간을 나타내는 가장 좋은 방법입니다.
long start = System.nanoTime();
// do things...
long end = System.nanoTime();
Duration duration = Duration.ofNanos(end - start);
System.out.println(duration); // Prints "PT18M19.511627776S"
System.out.printf("%d Hours %d Minutes %d Seconds%n",
duration.toHours(), duration.toMinutes() % 60, duration.getSeconds() % 60);
// prints "0 Hours 18 Minutes 19 Seconds"
시차가 1 시간 미만임을 알고 있다면 다음 코드를 사용할 수 있습니다.
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c2.add(Calendar.MINUTE, 51);
long diff = c2.getTimeInMillis() - c1.getTimeInMillis();
c2.set(Calendar.MINUTE, 0);
c2.set(Calendar.HOUR, 0);
c2.set(Calendar.SECOND, 0);
DateFormat df = new SimpleDateFormat("mm:ss");
long diff1 = c2.getTimeInMillis() + diff;
System.out.println(df.format(new Date(diff1)));
결과는 다음과 같습니다. 51:00
이 답변은 위의 답변과 비슷합니다. 그러나 다른 답변과 달리 쉼표 또는 공백을 제거하고 약어를 처리하기 때문에 이점이 있다고 생각합니다.
/**
* Converts milliseconds to "x days, x hours, x mins, x secs"
*
* @param millis
* The milliseconds
* @param longFormat
* {@code true} to use "seconds" and "minutes" instead of "secs" and "mins"
* @return A string representing how long in days/hours/minutes/seconds millis is.
*/
public static String millisToString(long millis, boolean longFormat) {
if (millis < 1000) {
return String.format("0 %s", longFormat ? "seconds" : "secs");
}
String[] units = {
"day", "hour", longFormat ? "minute" : "min", longFormat ? "second" : "sec"
};
long[] times = new long[4];
times[0] = TimeUnit.DAYS.convert(millis, TimeUnit.MILLISECONDS);
millis -= TimeUnit.MILLISECONDS.convert(times[0], TimeUnit.DAYS);
times[1] = TimeUnit.HOURS.convert(millis, TimeUnit.MILLISECONDS);
millis -= TimeUnit.MILLISECONDS.convert(times[1], TimeUnit.HOURS);
times[2] = TimeUnit.MINUTES.convert(millis, TimeUnit.MILLISECONDS);
millis -= TimeUnit.MILLISECONDS.convert(times[2], TimeUnit.MINUTES);
times[3] = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
StringBuilder s = new StringBuilder();
for (int i = 0; i < 4; i++) {
if (times[i] > 0) {
s.append(String.format("%d %s%s, ", times[i], units[i], times[i] == 1 ? "" : "s"));
}
}
return s.toString().substring(0, s.length() - 2);
}
/**
* Converts milliseconds to "x days, x hours, x mins, x secs"
*
* @param millis
* The milliseconds
* @return A string representing how long in days/hours/mins/secs millis is.
*/
public static String millisToString(long millis) {
return millisToString(millis, false);
}
문제가 있습니다. 밀리 초가 59999 인 경우 실제로 1 분이지만 59 초로 계산되고 999 밀리 초가 손실됩니다.
다음은 이전 답변을 기반으로 수정 된 버전으로,이 손실을 해결할 수 있습니다.
public static String formatTime(long millis) {
long seconds = Math.round((double) millis / 1000);
long hours = TimeUnit.SECONDS.toHours(seconds);
if (hours > 0)
seconds -= TimeUnit.HOURS.toSeconds(hours);
long minutes = seconds > 0 ? TimeUnit.SECONDS.toMinutes(seconds) : 0;
if (minutes > 0)
seconds -= TimeUnit.MINUTES.toSeconds(minutes);
return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds);
}
이것은 Java 9에서 더 쉽습니다.
Duration elapsedTime = Duration.ofMillis(millisDiff );
String humanReadableElapsedTime = String.format(
"%d hours, %d mins, %d seconds",
elapsedTime.toHours(),
elapsedTime.toMinutesPart(),
elapsedTime.toSecondsPart());
이 같은 문자열을 생성합니다 0 hours, 39 mins, 9 seconds
.
포맷하기 전에 초 단위로 반올림하려는 경우 :
elapsedTime = elapsedTime.plusMillis(500).truncatedTo(ChronoUnit.SECONDS);
시간이 0 인 경우 시간을 제외하려면 :
long hours = elapsedTime.toHours();
String humanReadableElapsedTime;
if (hours == 0) {
humanReadableElapsedTime = String.format(
"%d mins, %d seconds",
elapsedTime.toMinutesPart(),
elapsedTime.toSecondsPart());
} else {
humanReadableElapsedTime = String.format(
"%d hours, %d mins, %d seconds",
hours,
elapsedTime.toMinutesPart(),
elapsedTime.toSecondsPart());
}
이제 우리는 예를 들어 가질 수 있습니다 39 mins, 9 seconds
.
항상 0을 사용하여 분과 초를 인쇄하여 항상 두 자리 숫자로 만들 02
려면 관련 형식 지정자에 삽입 하십시오.
String humanReadableElapsedTime = String.format(
"%d hours, %02d mins, %02d seconds",
elapsedTime.toHours(),
elapsedTime.toMinutesPart(),
elapsedTime.toSecondsPart());
이제 우리는 예를 들어 가질 수 있습니다 0 hours, 39 mins, 09 seconds
.
if
- else
가.
올바른 문자열 ( "1 시간, 3 초", "3 분"이지만 "0 시간, 0 분, 3 초"는 아님)에 대해이 코드를 작성합니다.
int seconds = (int)(millis / 1000) % 60 ;
int minutes = (int)((millis / (1000*60)) % 60);
int hours = (int)((millis / (1000*60*60)) % 24);
int days = (int)((millis / (1000*60*60*24)) % 365);
int years = (int)(millis / 1000*60*60*24*365);
ArrayList<String> timeArray = new ArrayList<String>();
if(years > 0)
timeArray.add(String.valueOf(years) + "y");
if(days > 0)
timeArray.add(String.valueOf(days) + "d");
if(hours>0)
timeArray.add(String.valueOf(hours) + "h");
if(minutes>0)
timeArray.add(String.valueOf(minutes) + "min");
if(seconds>0)
timeArray.add(String.valueOf(seconds) + "sec");
String time = "";
for (int i = 0; i < timeArray.size(); i++)
{
time = time + timeArray.get(i);
if (i != timeArray.size() - 1)
time = time + ", ";
}
if (time == "")
time = "0 sec";
@MyKuLLSKI의 답변을 수정하고 plurlization 지원을 추가했습니다. 필요하지 않기 때문에 몇 초가 걸렸지 만 필요한 경우 다시 추가해도됩니다.
public static String intervalToHumanReadableTime(int intervalMins) {
if(intervalMins <= 0) {
return "0";
} else {
long intervalMs = intervalMins * 60 * 1000;
long days = TimeUnit.MILLISECONDS.toDays(intervalMs);
intervalMs -= TimeUnit.DAYS.toMillis(days);
long hours = TimeUnit.MILLISECONDS.toHours(intervalMs);
intervalMs -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(intervalMs);
StringBuilder sb = new StringBuilder(12);
if (days >= 1) {
sb.append(days).append(" day").append(pluralize(days)).append(", ");
}
if (hours >= 1) {
sb.append(hours).append(" hour").append(pluralize(hours)).append(", ");
}
if (minutes >= 1) {
sb.append(minutes).append(" minute").append(pluralize(minutes));
} else {
sb.delete(sb.length()-2, sb.length()-1);
}
return(sb.toString());
}
}
public static String pluralize(long val) {
return (Math.round(val) > 1 ? "s" : "");
}
int intervalMins
vs long millis
나는 이것을 다른 대답으로 다루었 지만 당신은 할 수 있습니다 :
public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {
long diffInMillies = date2.getTime() - date1.getTime();
List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
Collections.reverse(units);
Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
long milliesRest = diffInMillies;
for ( TimeUnit unit : units ) {
long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
long diffInMilliesForUnit = unit.toMillis(diff);
milliesRest = milliesRest - diffInMilliesForUnit;
result.put(unit,diff);
}
return result;
}
출력은 다음과 같습니다 Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}
단위가 주문 된 .
대상 로케일에 따라이 데이터를 국제화하는 방법을 찾는 것은 사용자의 몫입니다.
java.util.concurrent.TimeUnit을 사용하고이 간단한 메소드를 사용하십시오.
private static long timeDiff(Date date, Date date2, TimeUnit unit) {
long milliDiff=date2.getTime()-date.getTime();
long unitDiff = unit.convert(milliDiff, TimeUnit.MILLISECONDS);
return unitDiff;
}
예를 들면 다음과 같습니다.
SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
Date firstDate = sdf.parse("06/24/2017 04:30:00");
Date secondDate = sdf.parse("07/24/2017 05:00:15");
Date thirdDate = sdf.parse("06/24/2017 06:00:15");
System.out.println("days difference: "+timeDiff(firstDate,secondDate,TimeUnit.DAYS));
System.out.println("hours difference: "+timeDiff(firstDate,thirdDate,TimeUnit.HOURS));
System.out.println("minutes difference: "+timeDiff(firstDate,thirdDate,TimeUnit.MINUTES));
System.out.println("seconds difference: "+timeDiff(firstDate,thirdDate,TimeUnit.SECONDS));