我要计算用户的睡眠时间,他应该在他睡觉时和醒来时输入,我应该计算出他睡了多少小时
例如,如果用户输入
His sleeping time : 11:00 pm
His waking up time : 7:30 am
The number of sleeping hours should be : 8:30 hrs
有什么方法可以轻松进行此计算
这是代码
cal.set(Calendar.HOUR_OF_DAY, 11);
cal.set(Calendar.MINUTE, 0);
sleepTimeOnOffDays = cal.getTime();
private long subtractTwoDates(Date date1, Date date2) {
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.setTime(date1);
calendar2.setTime(date2);
long milsecs1 = calendar1.getTimeInMillis();
long milsecs2 = calendar2.getTimeInMillis();
long diff = milsecs2 - milsecs1;
long dhours = diff / (60 * 60 * 1000);
return Math.abs(dhours);
}
答案 0 :(得分:2)
从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,那么我建议使用@Ole VV在评论中建议的ThreeTen Android Backport API下面。
语法与java.time API几乎相同。上面的代码段也适用于ThreeTen Android Backport API(例如已经提到的@Basil Bourque),但有一个例外。不幸的是,ThreeTen Android Backport API的Duration
类没有提供用于从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,只需将其dependency包含到您的项目中即可。
答案 1 :(得分:2)
11:00 PM到7:30 AM = 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()
请参阅此code run live at IdeOne.com。
PT8H30M
The Answer是正确的方法,但无法解决诸如夏令时(DST)之类的异常情况。
您的问题不太清楚。您是要使用24小时通用工作日来跟踪时间的一般想法吗?还是要跟踪实际时刻,例如前两天的睡眠时间,昨天的时间等等?
如果是后者,则不能使用LocalDateDate
,因为根据定义,该类无法跟踪力矩。 LocalDateTime
类缺少任何时区或UTC偏移量的概念。因此,LocalDateTime
表示沿大约26-27小时(全球时区范围)范围内的潜在时刻。
以您的示例从11:00 pm到7:30 am,这意味着在特定时区的8.5个小时,该日期没有异常。但是在DST转换的一天,这可能意味着7.5个小时(“春季提前”)或9.5个小时(“回退”)。或者,例如去年North Korea adjusted their clock一天半小时,则为8.0小时(例如去年)。或在2007年Venezuela turned back time a half-hour… and then a decade later flipped back again时。这些更改比您可能意识到的发生得更多。全球各地的政客都对重新定义其时区的偏移表现出了浓厚的兴趣。
➥结果是您不能仅靠一天中的时间可靠地计算经过时间。您必须使用日期和时区。
ZoneId
以Continent/Region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
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 ) ;
我建议您使用时间格式HH:MM:SS 不报告经过时间。而是使用format defined for this purpose标准中的标准ISO 8601。
因此,PT8H30M
将是8.5小时。
java.time 类在解析/生成字符串时默认使用ISO 8601格式。
String output = d.toString() ; // Generate `PT8H30M`.
然后解析。
Duration d = Duration.parse( "PT8H30M" ) ;
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 2 :(得分:0)
您可以使用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");
我希望它能回答您的查询。谢谢:)
答案 3 :(得分:0)
只需尝试以下代码行,即可在几分钟内获得差异
import java.util.concurrent.TimeUnit; // predefined method from java 6.
private long subtractTwoDates(Date date1, Date date2) {
Long diffInMinutes=null,diff=null; // just declaration of variables
diff = date1.getTime() - date2.getTime();
diffInMinutes= TimeUnit.MILLISECONDS.toMinutes(diff);
log.info("diff min : "+difInMin);
return diffInMinutes; // returns long value in minutes.
}