首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为dayOfWeek创建日期和没有特定日期的时间,即对任何星期一都有效

为dayOfWeek创建日期和没有特定日期的时间,即对任何星期一都有效
EN

Stack Overflow用户
提问于 2018-09-27 15:51:11
回答 3查看 330关注 0票数 3

如何创建通用日期(即不附加于任何实际的yyMMdd,但类似于:

代码语言:javascript
运行
复制
val START = LocalTime.of(startHour, startMinute)
val END = LocalTime.of(endHour, endMinute)

但是,我还想包括dayOfWeek

我的意图是计算时间间隔的重叠,即对于两个给定的(开始和结束)时间戳,我想计算与指定的工作日和时间(如开放时间)的重叠。

编辑

我不确定定制类是否足够好。我的意图是,如果我有这样的事件清单:

代码语言:javascript
运行
复制
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

若要验证start-end的时间间隔是否与另一个时间间隔(即开放时间)相交,则其他时间间隔取决于周中的日期。

在构造对象之后(目前我的对象可能因为无法以通用方式组合dayOfWeek和Time )

我会使用isBefore/isAfter几次,然后计算重叠的持续时间。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-09-27 16:07:15

只需使用内置于Java中的DayOfWeek枚举即可。它提供了七个预定义的对象,一周中每天都有一个,比如DayOfWeek.MONDAY

我并不完全关注您的业务问题,但听起来您需要定义您自己的类。

代码语言:javascript
运行
复制
public class Shift {
    DayOfWeek dayOfWeek ;
    LocalTime startTime , stopTime ;
}

添加一种将其转化为真实时刻的方法。

代码语言:javascript
运行
复制
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 ;
}

您可能会想要向项目中添加第三个额外的库。它提供了一些类,如IntervalLocalDateTime,您可能会发现它们很有用。这些类提供了一系列比较方法,如连接、重叠等。

看起来这个库缺少一个LocalTimeRange,所以可能需要自己的。也许还会把这样的课程捐给那个项目。

关于java.time

http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.DateCalendarSimpleDateFormat

http://www.joda.org/joda-time/项目现在在维护模式中,建议迁移到java.time类。

要了解更多信息,请参见http://docs.oracle.com/javase/tutorial/datetime/TOC.html。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC 4.2。不需要字符串,也不需要java.sql.*类。

在哪里获得java.time类?

  • Java 8Java 9Java 10Java 11和更高版本--捆绑实现的标准Java的一部分。
    • Java 9添加了一些次要的特性和修复。

  • Java 6Java 7
    • 大多数java.time功能都是在http://www.threeten.org/threetenbp/中移植到Java6&7中的。

  • 安卓
    • 较晚版本的Android实现的java.time类。
    • 对于早期的Android (<26),https://github.com/JakeWharton/ThreeTenABP项目采用了http://www.threeten.org/threetenbp/ (上面提到的)。见http://stackoverflow.com/q/38922754/642706

票数 2
EN

Stack Overflow用户

发布于 2018-09-27 16:33:24

一种简单的方法是为这些“标准”间隔使用枚举映射。

假设下面是计算重叠的方法:

代码语言:javascript
运行
复制
static int calculateOverlap(LocalTime expectedStartTime, LocalTime expectedEndTime, 
        LocalTime actualStartTime, LocalTime actualEndTime) {
    //calculate overlap...
}

您可以这样查找值(为了简单起见,可以使用带有两个Pair字段的自定义类):

代码语言:javascript
运行
复制
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

然后使用以下方法查找:

代码语言:javascript
运行
复制
MyEvent mondayEvent = ...

Pair<LocalTime, LocalTime> mondayHours = officialHours.get(DayOfWeek.MONDAY);
int overlap = calculateOverlap(mondayHours.getLeft(), mondayHours.getRight(),
        mondayEvent.getStart(), mondayEvent.getEnd());
票数 1
EN

Stack Overflow用户

发布于 2018-11-01 02:55:47

我的lib Time4J (v5.0)为您的整个业务问题提供了以下开箱即用的解决方案:

代码语言:javascript
运行
复制
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)
            )));

输出:

事件:1 => 1:00 事件:2 => 0:00 活动:3 => 2:00

该算法使用量程包 of Time4J,如果每周有一个以上的时钟间隔,或者输入间隔超过一天(这需要对持续时间的总结),则仍能正常工作。

顺便说一句,我假设您的第一个间隔线“2018-01- 08:00,2018-01- 08:00”包含一个错误,所以我已经将结束时间调整为上午9点(结果是预期的持续时间为1小时)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52540796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档