您好我在尝试计算在不同周末的java中两个不同时间戳之间发生的24小时工作小时数时遇到问题。
String timestamp = rs.getString("timestamp");
String timeStamp = new SimpleDateFormat("yyyyMMddHH").format(new Date());
int currentTimeStamp = Integer.parseInt(timeStamp);
String orderTime = timestamp.replace("-", "");
String[] splitTimestamp = orderTime.split(" ");
String finalTimestamp = splitTimestamp[0] + splitTimestamp[1].substring(0,2);
int orderTimeStamp = Integer.parseInt(finalTimestamp);
这项目前确实有效,但包括周末。
如果有人能帮助我,我将非常感激。
这都是在东部时区完成的。
。周末不需要或不需要假期。答案 0 :(得分:3)
与最早版本的Java捆绑在一起的旧日期时间类设计糟糕,令人困惑且麻烦。避免使用java.util.Date/.Calendar等。
使用Java 8及更高版本中内置的java.time框架。或者它的Java 7&的后端口6.见Oracle Tutorial。
我没有尝试过运行此代码;就在我的头顶。 从不运行,从未进行过测试。可能会给你一个开始。
该问题似乎表明我们希望假定通用的24小时工作日而不是实际工作日(由于夏令时等异常情况,这些工作日可能会有所不同)。在通用日的情况下,我们不关心时区。我们可以使用LocalDateTime
类。
如果开始时间是周末,请将其移至下周一的第一个时刻。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMddHH" );
LocalDateTime start = LocalDateTime.parse( "2016010123" , formatter );
// If on a weekend, move to first moment of Monday.
if( start.getDayOfWeek().equals( DayOfWeek.SATURDAY ) {
start = start.plusDays( 2 ).toLocalDate().atStartOfDay();
}
if( start.getDayOfWeek().equals( DayOfWeek.SUNDAY ) {
start = start.plusDays( 1 ).toLocalDate().atStartOfDay();
}
同样停止。如果在周末,请转到下周一的第一时刻。
LocalDateTime stop = LocalDateTime.parse( "2016010723" , formatter );
// If on a weekend, move to first moment of Monday.
if( stop.getDayOfWeek().equals( DayOfWeek.SATURDAY ) {
stop = stop.plusDays( 2 ).toLocalDate().atStartOfDay();
}
if( stop.getDayOfWeek().equals( DayOfWeek.SUNDAY ) {
stop = stop.plusDays( 1 ).toLocalDate().atStartOfDay();
}
如果开始与停止相同,我们就完成了:报告零。
if( start.isEqual( stop ) ) {
return 0;
}
如果开始在停止之后,我们会出现错误情况。抛出异常,尝试纠正问题,或报告零,无论你的应用程序有什么意义。
if( start.isAfter( stop ) ) {
return 0; // Or consider it a problem, throw exception.
}
让我们将这个问题分为三个部分:
为了表示部分日期,我们使用Duration
类。 Duration
是一个时间跨度跟踪的总秒数加上纳秒。
第一部分从start
开始到第二天的第一时刻。
LocalDateTime firstMomentOfDayAfterStart = start.toLocalDate().plusDays(1).atStartOfDay();
Duration firstDayDuration = Duration.between( start , firstMomentOfDayAfterStart );
最后一个部分日从同一天的第一个时刻开始stop
。
LocalDateTime firstMomentOfDayOfStop = stop.toLocalDate().atStartOfDay();
Duration lastDayDuration = Duration.between( firstMomentOfDayOfStop , stop );
我们可以将每个Duration
转换为数小时。
int hoursFirstDay = firstDayDuration.toHours();
int hoursLastDay = lastDayDuration.toHours();
因此,我们有定义这些时间跨度的变量,如下图所示。请记住,这些是半开放的,每个范围的结尾是独占。
[ start > firstMomentOfDayAfterStart ][ firstMomentOfDayAfterStart > firstMomentOfDayOfStop ][ firstMomentOfDayOfStop > stop ]
现在在这对偏天之间循环整整一天。每天递增,连续一天测试工作日或周末。记住我们遇到的工作日。使用方便的DayOfWeek
enum进行比较。
int countWeekdays = 0;
LocalDateTime firstMomentOfSomeDay = firstMomentOfDayAfterStart
while( firstMomentOfSomeDay.isBefore( firstMomentOfDayOfStop ) ) {
DayOfWeek dayOfWeek = firstMomentOfSomeDay.getDayOfWeek();
if( dayOfWeek.equals( DayOfWeek.SATURDAY ) || dayOfWeek.equals( DayOfWeek.SUNDAY ) ) {
// ignore this day.
} else {
countWeekdays ++ ; // Tally another weekday.
}
// Set up the next loop.
firstMomentOfSomeDay = firstMomentOfSomeDay.plusDays( 1 );
}
我们可以使用TimeUnit
枚举将整天的计数转换为小时数。此转换假设为24小时通用。
int hoursOfWholeDays = TimeUnit.DAYS.toHours( countWeekDays ) ;
全部添加。
int totalHours = ( hoursFirstDay + hoursOfWholeDays + hoursLastDay ) ;
完成。返回总小时数。
return totalHours ;
如果您的数据通常包含很长一段时间,那么您可以考虑通过检测星期一和计算整周数来优化性能。我假设在业务场景中跟踪订单,间隔时间很短。所以这种优化不太可能很重要。
EnumSet
您可以替换该行:
if( dayOfWeek.equals( DayOfWeek.SATURDAY ) || dayOfWeek.equals( DayOfWeek.SUNDAY ) )…
...使用EnumSet
。
Set<DayOfWeek> weekend = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY ) ;
…
if( weekend.contains( dayOfWeek ) ) …
有关使用my answer to another Question课程的nextWorkingDay
和previousWorkingDay
方法检测周末的详细信息,请参阅Temporals
。这个类可以在扩展java.time框架的ThreeTen-Extra项目中找到。
此外,该类文档表明,编写自己的时态调整器以适合您的特定业务规则相对容易。
答案 1 :(得分:2)
我发现java.util.Calendar更干净,这是一个从3月1日(早上8点)到当前时间的小时数的例子:
git push origin master:test
答案 2 :(得分:0)
你可以这样做:
Date date1 = new Date(2016, 3, 21), date2 = new Date(2016, 4, 9);
int oneHour = 1000 * 60 * 60;
//Note that this rounds down the number of hours/days
int hours = (int)((date2.getTime() - date1.getTime()) / oneHour);
int days = hours / 24;
int day1, day2;
//set the values of day: [Sun=0, Mon=1, Tue=2, Wed=3, Thur=4, Fri=5, Sat=6]
//date.getDay() is supposed to do that, but it's deprecated
int nWEdays = days/7*2;
if(day2-day1 < 0) nWEdays += 2;
else {
if(day1 == 0 || day1 == 6) nWEdays++;
else if(day2 == 0 || day2 == 6) nWEdays++;
}
int weekendHours = hours - nWEdays*24;