3 回答
TA贡献1820条经验 获得超10个赞
从 Java SE 8 开始,我想建议使用java.time API。对于 Android 用户,在API 26+ 中添加了 java.time。
Java 8 为日期和时间引入了新的 API,以解决旧 java.util.Date 和 java.util.Calendar 的缺点。
使用 java.time API 计算两个日期时间之间的持续时间非常容易。
LocalDateTime localDateTime1 = LocalDateTime.now();
localDateTime1 = localDateTime1.withHour(23).withMinute(0).withSecond(0).withNano(0);
LocalDateTime localDateTime2 = LocalDateTime.now();
localDateTime2 = localDateTime2.plusDays(1).withHour(7).withMinute(30).withSecond(0).withNano(0);
Duration diff = Duration.between(localDateTime1, localDateTime2);
String hms = String.format("%d:%02d:%02d",
diff.toHoursPart(),
diff.toMinutesPart(),
diff.toSecondsPart());
System.out.println(hms);
-----------------------
Console output:
8:30:00
如果 java.time API 不适用于您的项目,例如您的项目尚未达到 API 级别 26,那么我建议使用ThreeTen Android Backport API,正如@Ole VV 在下面的评论中所建议的那样。
语法与 java.time API 几乎相同。上面的代码片段也适用于 ThreeTen Android Backport API(如 @Basil Bourque 已经提到的),但有一个例外。遗憾的是,ThreeTen Android Backport API的Duration类没有提供从持续时间对象中提取小时部分、分钟部分等的辅助方法。相反,当您使用反向端口时,您需要先减去小时数,然后从持续时间中减去分钟数,因此只剩下秒数:
long hours = diff.toHours();
diff = diff.minusHours(hours);
long minutes = diff.toMinutes();
diff = diff.minusMinutes(minutes);
long seconds = diff.getSeconds();
String hms = String.format("%d:%02d:%02d",
hours,
minutes,
seconds);
另一个区别是您需要从org.threeten.bp包(而不是java.time包)中导入 java.time 类。
如果您想使用 ThreeTen Backport API,只需将它的依赖项包含到您的项目中即可。
TA贡献1784条经验 获得超7个赞
晚上 11:00 到早上 7:30 = 7.5 或 8.0 或 8.5 或 9.5 或其他小时数,具体取决于特定日期和时区。
Duration.between(
ZonedDateTime.of( 2019 , 1 , 23 , 23 , 0 , 0 , 0 , ZoneId.of( "Africa/Cairo" ) ) ,
ZonedDateTime.of( 2019 , 1 , 24 , 7 , 30 , 0 , 0 , ZoneId.of( "Africa/Cairo" ) )
)
.toString()
请参阅在 IdeOne.com 上实时运行的代码。
PT8H30M
计算经过的时间需要日期、时间和时区
Markus Hänsel的答案是正确的,但未能解释夏令时 (DST) 等异常情况。
你的问题不是很清楚。您的意思是使用通用的 24 小时制来跟踪一天中时间的一般概念吗?或者您的意思是跟踪实际时刻,例如两天前的睡眠时间、昨天的睡眠时间等等?
如果是后者,那么您不能使用LocalDateDate该类,因为根据定义,该类不能跟踪时刻。该类LocalDateTime缺少任何时区或与 UTC 偏移的概念。因此,aLocalDateTime代表大约 26-27 小时(全球时区范围)范围内的潜在时刻。
以晚上 11:00 到早上 7:30 为例,这意味着在某个时区有 8.5 小时,并且在该日期没有异常。但是在 DST 切换的那一天,这可能意味着 7.5 小时(“提前”)或 9.5 小时(“回退”)。或者像去年朝鲜将时钟调整半小时那样一天可能是 8.0 小时。或者当 2007 年委内瑞拉将时间倒转半小时……然后十年后再次倒转。这些变化发生的频率比你想象的要多。世界各地的政客都表现出重新定义其时区偏移的倾向。
➥ 结果是您无法仅使用时间可靠地计算经过的时间。您必须使用日期和时区。
ZoneId
以、或等格式指定适当的时区名称。永远不要使用 2-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。Continent/RegionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime
要跟踪时刻,请使用ZonedDateTime类。此类结合了日期、时间和时区。
LocalDate ldStart = LocalDate.of( 2019 , 1 , 23 ) ;
LocalTime ldStart = LocalTime.of( 23 , 0 ) ;
ZonedDateTime zdtStart = ZonedDateTime.of( ldStart , ltStart , z ) ;
和停止时间。
LocalDate ldStop = LocalDate.of( 2019 , 1 , 24 ) ; // Next day.
LocalTime ldStop = LocalTime.of( 7 , 30 ) ;
ZonedDateTime zdtStop = ZonedDateTime.of( ldStop , ltStop , z ) ;
Duration使用类计算经过的时间。
Duration d = Duration.between( zdtStart , zdtStop ) ;
ISO 8601
我建议您不要使用时间格式 HH:MM:SS 报告经过的时间。而是使用ISO 8601标准中为此目的定义的标准格式。
因此,8.5 小时将是PT8H30M.
java.time类在解析/生成字符串时默认使用 ISO 8601 格式。
String output = d.toString() ; // Generate `PT8H30M`.
并解析。
Duration d = Duration.parse( "PT8H30M" ) ;
TA贡献1843条经验 获得超7个赞
您可以使用SimpleDateFormat获取输入。我正在使用预定义的输入,因为您想要计算两个给定时间之间的差异。这是你的代码。请注意,我已经给出了 24 小时或 12 小时格式的答案。
获取睡眠时间和醒来时间的值
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
Date sleepingTime = simpleDateFormat.parse("22:00");
Date wakeUptime = simpleDateFormat.parse("07:00");
对于差异小于零,这以 12 小时格式发生
long difference = sleepingTime.getTime() - wakeUpTime.getTime();
if(difference<0) {
Date dateMax = simpleDateFormat.parse("24:00");
Date dateMin = simpleDateFormat.parse("00:00");
difference=(dateMax.getTime() -sleepingTime.getTime() )+(wakeUpTime.getTime()-
dateMin.getTime());
}
计算差异
//days and minutes are optional
int days = (int) (difference / (1000*60*60*24));
int hours = (int) ((difference - (1000*60*60*24*days)) / (1000*60*60));
int min = (int) (difference - (1000*60*60*24*days) - (1000*60*60*hours)) /
(1000*60);
Log.e("log_tag",hours+" hours");
我希望它能回答你的问题。谢谢 :)
添加回答
举报
