代码之家  ›  专栏  ›  技术社区  ›  Georg Heiler

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

  •  2
  • Georg Heiler  · 技术社区  · 7 年前

    如何创建通用日期(即不附加到任何实际日期) 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
    

    验证 start-end 与另一个时间间隔(即开放时间)相交,但此其他时间间隔取决于一周中的哪一天。

    在构造对象之后(我现在有可能是因为我不能以通用的方式组合dayOfWeek和Time)

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

    3 回复  |  直到 7 年前
        1
  •  2
  •   Basil Bourque    7 年前

    就用这个 DayOfWeek 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 ;
    }
    

    您可能需要添加 额外的310 Interval LocalDateTime 桥台 重叠 等等。

    看起来那个图书馆缺少一个 LocalTimeRange ,所以你可能想自己滚。甚至可以为那个项目捐赠这样的课程。


    关于 java.time文件

    java.time legacy java.util.Date , Calendar ,& SimpleDateFormat .

    这个 Joda-Time 项目,正在进行中 maintenance mode ,建议迁移到 java.time

    要了解更多信息,请参阅 Oracle Tutorial . 和搜索堆栈溢出的许多例子和解释。规格为 JSR 310 .

    你可以交换 java.time文件 对象直接与数据库连接。使用 JDBC driver 符合 JDBC 4.2 或者更晚。不需要线,不需要线 java.sql.* 班级。

        2
  •  1
  •   ernest_k Petronella    7 年前

    假设采用以下方法计算重叠:

    static int calculateOverlap(LocalTime expectedStartTime, LocalTime expectedEndTime, 
            LocalTime actualStartTime, LocalTime actualEndTime) {
        //calculate overlap...
    }
    

    您可以用这种方式查找值(使用 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
    

    然后使用以下方法查找:

    MyEvent mondayEvent = ...
    
    Pair<LocalTime, LocalTime> mondayHours = officialHours.get(DayOfWeek.MONDAY);
    int overlap = calculateOverlap(mondayHours.getLeft(), mondayHours.getRight(),
            mondayEvent.getStart(), mondayEvent.getEnd());
    
        3
  •  1
  •   Community Mohan Dere    5 年前

    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)
                )));
    

    输出:

    事件:2=>0:00

    算法使用 range-package 如果一周中每天有一个以上的时钟间隔,或者输入间隔超过一天(需要对持续时间求和),则仍然可以正常工作。