如何计算 Java 中的时间跨度并格式化输出?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/635935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I calculate a time span in Java and format the output?
提问by Jeremy Logan
I want to take two times (in seconds since epoch) and show the difference between the two in formats like:
我想两次(自纪元以来的秒数)并以以下格式显示两者之间的差异:
- 2 minutes
- 1 hour, 15 minutes
- 3 hours, 9 minutes
- 1 minute ago
- 1 hour, 2 minutes ago
- 2分钟
- 1小时15分钟
- 3小时9分钟
- 1 分钟前
- 1 小时 2 分钟前
How can I accomplish this??
我怎样才能做到这一点?
采纳答案by BalusC
Since everyone shouts "YOODAA!!!" but noone posts a concrete example, here's my contribution.
由于每个人都在喊“YOODAA!!!” 但没有人发布一个具体的例子,这是我的贡献。
You could also do this with Joda-Time. Use Period
to represent a period. To format the period in the desired human representation, use PeriodFormatter
which you can build by PeriodFormatterBuilder
.
您也可以使用Joda-Time执行此操作。使用Period
代表一个时期。要在所需的人类表示中格式化句点,请使用PeriodFormatter
您可以通过PeriodFormatterBuilder
.
Here's a kickoff example:
这是一个启动示例:
DateTime myBirthDate = new DateTime(1978, 3, 26, 12, 35, 0, 0);
DateTime now = new DateTime();
Period period = new Period(myBirthDate, now);
PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendYears().appendSuffix(" year, ", " years, ")
.appendMonths().appendSuffix(" month, ", " months, ")
.appendWeeks().appendSuffix(" week, ", " weeks, ")
.appendDays().appendSuffix(" day, ", " days, ")
.appendHours().appendSuffix(" hour, ", " hours, ")
.appendMinutes().appendSuffix(" minute, ", " minutes, ")
.appendSeconds().appendSuffix(" second", " seconds")
.printZeroNever()
.toFormatter();
String elapsed = formatter.print(period);
System.out.println(elapsed + " ago");
Much more clear and concise, isn't it?
更加简洁明了,不是吗?
This prints by now
这现在打印
32 years, 1 month, 1 week, 5 days, 6 hours, 56 minutes, 24 seconds ago
(Cough, old, cough)
(咳,老,咳)
回答by TuxMeister
I'm not an expert in Java, but you can do t1-t2=t3(in seconds) then divide that by 60, would give you minutes, by another 60 would give you seconds. Then it's just a matter of figuring out how many divisions you need.
我不是 Java 专家,但你可以做 t1-t2=t3(以秒为单位)然后除以 60,得到分钟,再除以 60 得到秒。然后只需弄清楚您需要多少个部门。
Hope it helps.
希望能帮助到你。
回答by mr_urf
I always start with Joda Time. Working with dates and times in Java is always "fun" but Joda Time takes the strain off.
我总是从Joda Time开始。在 Java 中处理日期和时间总是“有趣”的,但 Joda Time 减轻了压力。
They have Interval and Duration classes which do half of what you are looking for. Not sure if they have a function for outputing in readable format though. I'll keep looking.
他们有 Interval 和 Duration 类,可以完成您正在寻找的一半。不确定他们是否具有以可读格式输出的功能。我会继续寻找。
HTH
HTH
回答by Ben S
The Calendarclass can handle most date related math. You will have to get the result of compareToand output the format yourself though. There isn't a standard library that does exactly what you're looking for, though there might be a 3rd party library that does.
该日历类可以处理大多数日期相关的数学。不过,您必须获得compareTo的结果并自己输出格式。没有一个标准库可以完全满足您的要求,尽管可能有一个 3rd 方库可以做到。
回答by Timo
long time1, time2;
time1 = System.currentMillis();
.. drink coffee
time2 = System.currentMillis();
long difference = time2 - time1 // millies between time1 and time2
java.util.Date differneceDate = new Date(difference);
To create a string like "2 Minutes" you should use DateFormatter/DateFormat. You can find more details on this in the the Java API spec (java.sun.com).
要创建像“2 分钟”这样的字符串,您应该使用 DateFormatter/DateFormat。您可以在 Java API 规范 (java.sun.com) 中找到更多详细信息。
回答by mr_urf
OK, after a brief peruse of the API it seems that you could do the following: -
好的,在简要阅读 API 之后,您似乎可以执行以下操作:-
- create some ReadableInstants representing start time and end time.
- Use Hours.hoursBetween to get the number of hours
- use Minutes.minutesBetween to get the number of minutes
- use mod 60 on the minutes to get the remaining minutes
- et voila!
- 创建一些 ReadableInstants 表示开始时间和结束时间。
- 使用 hours.hoursBetween 获取小时数
- 使用 Minutes.minutesBetween 获取分钟数
- 在分钟上使用 mod 60 来获取剩余的分钟数
- 等等!
HTH
HTH
回答by Timour
Date start = new Date(1167627600000L); // JANUARY_1_2007
Date end = new Date(1175400000000L); // APRIL_1_2007
long diffInSeconds = (end.getTime() - start.getTime()) / 1000;
long diff[] = new long[] { 0, 0, 0, 0 };
/* sec */diff[3] = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
/* min */diff[2] = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
/* hours */diff[1] = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
/* days */diff[0] = (diffInSeconds = (diffInSeconds / 24));
System.out.println(String.format(
"%d day%s, %d hour%s, %d minute%s, %d second%s ago",
diff[0],
diff[0] > 1 ? "s" : "",
diff[1],
diff[1] > 1 ? "s" : "",
diff[2],
diff[2] > 1 ? "s" : "",
diff[3],
diff[3] > 1 ? "s" : ""));
回答by Adrian Pronk
If your time-spans cross daylight-saving (summer-time) boundaries, do you want to report the number of days?
如果您的时间跨度跨越夏令时(夏令时)界限,您想报告天数吗?
For example, 23:00 to 23:00 the next day is always a day but may be 23, 24 or 25 hours depending on whether the you cross a daylight-savings transition.
例如,23:00 到第二天的 23:00 始终是一天,但可能是 23、24 或 25 小时,具体取决于您是否跨过夏令时过渡。
If you care about that, make sure you factor it into your choice.
如果您关心这一点,请确保将其纳入您的选择。
回答by Abduliam Rehmanius
Yup awakened the dead I have, but here's my improved implementation based on @mtim posted code, as this thread comes almost on top of the searches so I am messing with the sleepy hollow,
是的唤醒了我的死者,但这是我基于@mtim 发布的代码改进的实现,因为这个线程几乎位于搜索的顶部,所以我正在处理沉睡的空洞,
public static String getFriendlyTime(Date dateTime) {
StringBuffer sb = new StringBuffer();
Date current = Calendar.getInstance().getTime();
long diffInSeconds = (current.getTime() - dateTime.getTime()) / 1000;
/*long diff[] = new long[]{0, 0, 0, 0};
/* sec * diff[3] = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
/* min * diff[2] = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
/* hours * diff[1] = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
/* days * diff[0] = (diffInSeconds = (diffInSeconds / 24));
*/
long sec = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
long min = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
long hrs = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
long days = (diffInSeconds = (diffInSeconds / 24)) >= 30 ? diffInSeconds % 30 : diffInSeconds;
long months = (diffInSeconds = (diffInSeconds / 30)) >= 12 ? diffInSeconds % 12 : diffInSeconds;
long years = (diffInSeconds = (diffInSeconds / 12));
if (years > 0) {
if (years == 1) {
sb.append("a year");
} else {
sb.append(years + " years");
}
if (years <= 6 && months > 0) {
if (months == 1) {
sb.append(" and a month");
} else {
sb.append(" and " + months + " months");
}
}
} else if (months > 0) {
if (months == 1) {
sb.append("a month");
} else {
sb.append(months + " months");
}
if (months <= 6 && days > 0) {
if (days == 1) {
sb.append(" and a day");
} else {
sb.append(" and " + days + " days");
}
}
} else if (days > 0) {
if (days == 1) {
sb.append("a day");
} else {
sb.append(days + " days");
}
if (days <= 3 && hrs > 0) {
if (hrs == 1) {
sb.append(" and an hour");
} else {
sb.append(" and " + hrs + " hours");
}
}
} else if (hrs > 0) {
if (hrs == 1) {
sb.append("an hour");
} else {
sb.append(hrs + " hours");
}
if (min > 1) {
sb.append(" and " + min + " minutes");
}
} else if (min > 0) {
if (min == 1) {
sb.append("a minute");
} else {
sb.append(min + " minutes");
}
if (sec > 1) {
sb.append(" and " + sec + " seconds");
}
} else {
if (sec <= 1) {
sb.append("about a second");
} else {
sb.append("about " + sec + " seconds");
}
}
sb.append(" ago");
/*String result = new String(String.format(
"%d day%s, %d hour%s, %d minute%s, %d second%s ago",
diff[0],
diff[0] > 1 ? "s" : "",
diff[1],
diff[1] > 1 ? "s" : "",
diff[2],
diff[2] > 1 ? "s" : "",
diff[3],
diff[3] > 1 ? "s" : ""));*/
return sb.toString();
}
It obviously can be improved. basically it tries to get the time span more friendly, there are a few limitation though i.e. it would behave strangely if the time passed (parameter) is in future, and its limited up to the days, hours and seconds only (months and years not handled, so that someone else can ;-).
显然可以改进。基本上它试图让时间跨度更友好,但有一些限制,即如果传递的时间(参数)是未来的,它会表现得很奇怪,并且它仅限于天、小时和秒(不包括月和年)处理,以便其他人可以;-)。
sample outputs are:
样本输出是:
- about a second ago
- 8 minutes and 34 seconds ago
- an hour and 4 minutes ago
- a day ago
- 29 days ago
- a year and 3 months ago
- 大约一秒钟前
- 8 分 34 秒前
- 一小时四分钟前
- 一天前
- 29 天前
- 一年零三个月前
, cheers :D
,干杯:D
EDIT: now supports months and years :P
编辑:现在支持数月和数年:P