java为dayOfWeek和time创建日期,无特定日期,即对任何周一有效
如何创建通用日期(即不附加到任何实际的java为dayOfWeek和time创建日期,无特定日期,即对任何周一有效,java,localdate,Java,Localdate,如何创建通用日期(即不附加到任何实际的yyMMdd,但类似于: val START = LocalTime.of(startHour, startMinute) val END = LocalTime.of(endHour, endMinute) 但是,我还想包括dayOfWeek 我的目的是计算时间间隔的重叠,即对于两个给定的(开始、结束)时间戳,我希望计算与指定的工作日和时间(如开放时间)的重叠 编辑 我不确定定制类是否足够好。 我的意图是,如果我有一个事件列表,比如: id,start,
yyMMdd
,但类似于:
val START = LocalTime.of(startHour, startMinute)
val END = LocalTime.of(endHour, endMinute)
但是,我还想包括dayOfWeek
我的目的是计算时间间隔的重叠,即对于两个给定的(开始、结束)时间戳,我希望计算与指定的工作日和时间(如开放时间)的重叠
编辑
我不确定定制类是否足够好。
我的意图是,如果我有一个事件列表,比如:
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
验证开始-结束的时间间隔是否与另一个时间间隔(即营业时间)相交,但另一个时间间隔取决于星期几
在构建对象之后(我目前可能无法以通用方式将dayOfWeek和Time组合在一起)
我会使用isBefore/isAfter
几次,然后计算重叠的持续时间。只需使用Java内置的枚举即可。它提供了七个预定义对象,一周中的每一天一个,例如DayOfWeek.MONDAY
我并不完全了解您的业务问题,但听起来您需要定义自己的类
public class Shift {
DayOfWeek dayOfWeek ;
LocalTime startTime , stopTime ;
}
添加一种将其转化为真实时刻的方法
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 ;
}
您可能希望将Three Ten额外库添加到项目中。它提供了一些类,如Interval
和LocalDateTime
,您可能会发现这些类很有用。这些类提供了一系列比较方法,如邻接、重叠等
看起来这个库缺少一个LocalTimeRange
,所以你可能想要自己的。也许甚至可以把这样一个类捐赠给那个项目
关于java.time
该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,如,&
该项目现已启动,建议迁移到类
要了解更多信息,请参阅.和搜索堆栈溢出以获取许多示例和解释。规范为
您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要java.sql.*
classes
从哪里获得java.time类
- 、和更高版本-标准Java API的一部分,带有捆绑实现。
- Java9添加了一些次要功能和修复
- 及
- 大多数java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(一个简单的方法是对那些“标准”间隔使用枚举映射
假设采用以下方法计算重叠:
static int calculateOverlap(LocalTime expectedStartTime, LocalTime expectedEndTime,
LocalTime actualStartTime, LocalTime actualEndTime) {
//calculate overlap...
}
您可以通过这种方式查找值(使用Pair
为简单起见,您可以使用带有两个LocalTime
字段的自定义类):
Map openingHours=
新的EnumMap(DayOfWeek.class);
开放小时。放(星期一,星期一),
对(LocalTime.of(8,0),LocalTime.of(16,0));
开放时间:星期二,
对(LocalTime.of(9,0),LocalTime.of(17,0));
//…其他工作日的参赛作品
然后使用以下命令进行查找:
MyEvent mondayEvent = ...
Pair<LocalTime, LocalTime> mondayHours = officialHours.get(DayOfWeek.MONDAY);
int overlap = calculateOverlap(mondayHours.getLeft(), mondayHours.getRight(),
mondayEvent.getStart(), mondayEvent.getEnd());
MyEvent mondayEvent=。。。
Pair mondayHours=officialHours.get(DayOfWeek.周一);
int overlap=calculateOverlap(mondayHours.getLeft(),mondayHours.getRight(),
mondayEvent.getStart(),mondayEvent.getEnd();
My lib(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)
)));
DayPartitionRule规则=
new DayPartitionBuilder()
.addWeekdayRule(
工作日,星期一,
时钟间隔介于(8,0的纯时间,10,0的纯时间)
.addWeekdayRule(
工作日,星期二,
时钟间隔介于(10,0的纯时间,15,0的纯时间)
.build();
映射事件=新的HashMap();
events.put(
1.
时间间隔(
时间戳(2018,1,1,8,0),
(2018年1月1日9月0日)的时间戳;
events.put(
2.
时间间隔(
时间戳(2018年1月1日10日0日),
(2018,1,1,12,0)的时间戳;
events.put(
3.
时间间隔(
时间戳(2018年1月2日10月0日),
(2018年1月2日12月0日)的时间戳;
事件。forEach(
(id,间隔)->System.out.println(
“事件:+id+”=>”
+Duration.formatter(ClockUnit.class,#h:mm”).format(
间隔
.streamPartitioned(规则)
.map(i->i.getDuration(ClockUnit.HOURS,ClockUnit.MINUTES))
.collect(Duration.summingUp())
.带(持续时间标准时钟周期)
)));
输出:
事件:1=>1:00
事件:2=>0:00
事件:3=>2:00
该算法使用Time4J的值,如果一周中每天有多个时钟间隔,或者输入间隔超过一天(这需要对持续时间求和),则该算法仍能正常工作
顺便说一句,我假设您的第一个间隔行“2018-01-01 08:00,2018-01-01 08:00”包含一个打字错误,因此我将结束时间调整为上午9点(预计持续时间为一小时)。好主意。但是,我不确定如何将此枚举与开放时间相结合,例如:LocalDateTime.of(星期五,8,0)
将不会compile@GeorgHeiler您创建了一个类DayOfWeekTime
,包含两个字段:dayOfWeek
和time
。这看起来非常有趣。基本上@Basil在您的链接答案之后,间隔重叠处理的状态是否发生了变化?@GeorgHeiler不确定您针对该链接问题询问了什么。Reg额外添加三个十,并计算重叠间隔。对于具有3个字段的类:dayOfWeek
,startTime
,
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)
)));