[英]java create date for dayOfWeek and time without a specific date, i.e. valid for any Monday
How can I create a generic date (ie not attached to any actual yyMMdd
but similar to: 如何创建通用日期(即未附加到任何实际的
yyMMdd
但类似于:
val START = LocalTime.of(startHour, startMinute)
val END = LocalTime.of(endHour, endMinute)
However, I additionally want to include the dayOfWeek
. 但是,我还想包含
dayOfWeek
。
My intention is to calculate the overlap of time intervals, ie for two given (start, end) timestamps I want to calculate overlap with a specified weekday and time (ie like opening hours). 我的意图是计算时间间隔的重叠,即对于两个给定的(开始,结束)时间戳,我想计算与指定的工作日和时间(例如开放时间)的重叠。
I am not sure if a custom class is good enough. 我不确定自定义类是否足够好。 My intention is if I have a list of events like:
我的意图是,如果我有以下事件列表:
id,start,end
1,2018-01-01 08:00, 2018-01-01 08:00 || opening hours 8-10, duration: 1
2,2018-01-01 10:00, 2018-01-01 12:00 || opening hours 8-10, duration: 0
3,2018-01-02 10:00, 2018-01-02 12:00 || opening hours 10-15, duration 2
to validate if time interval of start-end
intersects with another time interval (ie opening hours), but this other time interval depends on the day of week. 验证
start-end
时间间隔是否与另一个时间间隔(即营业时间)相交,但是该另一个时间间隔取决于星期几。
After constructing the object (where I currently have my probably as I can't combine dayOfWeek and Time in a generic way) 构造对象后(由于无法将dayOfWeek和Time以通用方式结合在一起,因此我目前拥有该对象)
I would use isBefore/isAfter
a couple of times and then calculate the duration of overlap. 我将使用
isBefore/isAfter
几次,然后计算重叠的持续时间。
Just use the DayOfWeek
enum built into Java. 只需使用Java内置的
DayOfWeek
枚举即可。 It offers seven predefined objects, one for every day of the week, such as DayOfWeek.MONDAY
. 它提供了七个预定义的对象,每个星期的一天都有一个对象,例如
DayOfWeek.MONDAY
。
I don't follow exactly your business problem, but it sounds like you need to define your own class. 我没有完全解决您的业务问题,但是听起来您需要定义自己的类。
public class Shift {
DayOfWeek dayOfWeek ;
LocalTime startTime , stopTime ;
}
Add a method that translates that into real moments. 添加一种将其转化为真实时刻的方法。
public ZonedDateTime startAtDate( LocalDate ld , ZoneId z ) {
LocalDate LocalDate = ld.with( TemporalAdjustors.previousOrSame( this.dayOfWeek ) ) ;
ZonedDateTime zdt = ZonedDateTime.of( localDate , this.startTime , z ) ;
return zdt ;
}
You'll likely want to add the ThreeTen-Extra library to your project. 您可能需要将ThreeTen-Extra库添加到您的项目中。 It offers classes such as
Interval
and LocalDateTime
that you might find useful. 它提供了诸如
Interval
和LocalDateTime
类的类,这些类可能对您有用。 These classes offer a bunch of comparison methods such as abuts , overlaps , etc. 这些类提供了一堆比较方法,例如邻接 , 重叠等。
Looks like that library lacks a LocalTimeRange
, so might want to roll your own. 看起来该库缺少
LocalTimeRange
,因此可能需要自己滚动。 Perhaps even donate such a class to that project. 甚至可以向该项目捐赠此类课程。
The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as
java.util.Date
, Calendar
, & SimpleDateFormat
. 这些类取代了麻烦的旧的旧式日期时间类,例如
java.util.Date
, Calendar
和SimpleDateFormat
。
The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial . 要了解更多信息,请参见Oracle教程 。 And search Stack Overflow for many examples and explanations.
并在Stack Overflow中搜索许多示例和说明。 Specification is JSR 310 .
规格为JSR 310 。
You may exchange java.time objects directly with your database. 您可以直接与数据库交换java.time对象。 Use a JDBC driver compliant with JDBC 4.2 or later.
使用与JDBC 4.2或更高版本兼容的JDBC驱动程序 。 No need for strings, no need for
java.sql.*
classes. 不需要字符串,不需要
java.sql.*
类。
Where to obtain the java.time classes? 在哪里获取java.time类?
One simple approach is to use an enum map for those "standard" intervals. 一种简单的方法是为那些“标准”间隔使用一个枚举映射。
Assuming the method below to calculate the overlap: 假设采用以下方法计算重叠:
static int calculateOverlap(LocalTime expectedStartTime, LocalTime expectedEndTime,
LocalTime actualStartTime, LocalTime actualEndTime) {
//calculate overlap...
}
You can look up the value in this way (using Pair
for simplicity, you can use a custom class with two LocalTime
fields): 您可以通过这种方式查找值(为简单起见,使用
Pair
,可以将自定义类与两个LocalTime
字段一起使用):
Map<DayOfWeek, Pair<LocalTime, LocalTime>> openingHours =
new EnumMap<>(DayOfWeek.class);
openingHours.put(DayOfWeek.MONDAY,
Pair.of(LocalTime.of(8, 0), LocalTime.of(16, 0)));
openingHours.put(DayOfWeek.TUESDAY,
Pair.of(LocalTime.of(9, 0), LocalTime.of(17, 0)));
//...entries for other weekdays
And then look it up using: 然后使用以下命令查找它:
MyEvent mondayEvent = ...
Pair<LocalTime, LocalTime> mondayHours = officialHours.get(DayOfWeek.MONDAY);
int overlap = calculateOverlap(mondayHours.getLeft(), mondayHours.getRight(),
mondayEvent.getStart(), mondayEvent.getEnd());
My lib Time4J (v5.0) offers following out-of-box-solution for your whole business problem: 我的lib Time4J (v5.0)为您的整个业务问题提供了以下现成的解决方案:
DayPartitionRule rule =
new DayPartitionBuilder()
.addWeekdayRule(
Weekday.MONDAY,
ClockInterval.between(PlainTime.of(8, 0), PlainTime.of(10, 0)))
.addWeekdayRule(
Weekday.TUESDAY,
ClockInterval.between(PlainTime.of(10, 0), PlainTime.of(15, 0)))
.build();
Map<Integer, TimestampInterval> events = new HashMap<>();
events.put(
1,
TimestampInterval.between(
PlainTimestamp.of(2018, 1, 1, 8, 0),
PlainTimestamp.of(2018, 1, 1, 9, 0)));
events.put(
2,
TimestampInterval.between(
PlainTimestamp.of(2018, 1, 1, 10, 0),
PlainTimestamp.of(2018, 1, 1, 12, 0)));
events.put(
3,
TimestampInterval.between(
PlainTimestamp.of(2018, 1, 2, 10, 0),
PlainTimestamp.of(2018, 1, 2, 12, 0)));
events.forEach(
(id, interval) -> System.out.println(
"Event: " + id + " => "
+ Duration.formatter(ClockUnit.class, "#h:mm").format(
interval
.streamPartitioned(rule)
.map(i -> i.getDuration(ClockUnit.HOURS, ClockUnit.MINUTES))
.collect(Duration.summingUp())
.with(Duration.STD_CLOCK_PERIOD)
)));
Output: 输出:
Event: 1 => 1:00
事件:1 => 1:00
Event: 2 => 0:00
事件:2 => 0:00
Event: 3 => 2:00
事件:3 => 2:00
The algorithm uses the range-package of Time4J and still works properly if you have more than one clock interval per day-of-week or if the input interval stretches over more than one day (which requires summing up durations). 该算法使用Time4J的范围包 ,并且如果您每个星期的一天中有多个时钟间隔,或者输入间隔超过一天(这需要汇总持续时间),则该算法仍然可以正常工作。
By the way, I assume that your first interval line "2018-01-01 08:00, 2018-01-01 08:00" contains a typo so I have adjusted the end time to 9AM (resulting in the expected duration of one hour). 顺便说一句,我假设您的第一个间隔行“ 2018-01-01 08:00,2018-01-01 08:00”包含一个错字,因此我将结束时间调整为9AM(导致预期的持续时间为小时)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.