java设置周末不可选_如何添加营业时间到日期考虑不添加周末? - Java的

避免旧日期,时间类

您使用的是已被证明是设计不良的旧日期时间类,混乱和麻烦。避免它们。

java。时间

使用内置于Java 8及更高版本中的java.time框架。见Tutorial。对于Java 6 & 7,请使用ThreeTen-Backport项目。对于Android,该后端端口的改编,ThreeTenABP。

下面是一些示例代码,让你去。我只是马上掀起了这个,所以它可能不健壮。此代码似乎为你一个例子使用工作:

(周五18:00)+ 48 =(Tuseday 18:00)(周六,周日被忽略)

我概括这个代码一点点。而不是几个小时,在任何时间段(内部表示为总秒数加上几分之一秒(纳秒))需要Duration。您会注意到toString方法的输出使用标准的ISO 8601表示法,例如PT48H用于48小时的示例。

假设您想要时间线上的真实时刻,我们需要使用时区来解释夏令时(DST)等异常情况。为此,我们需要以ZonedDateTime开头,其中结合了UTC(Instant)时间轴上的时刻与时区(ZoneId)。

我们还传递一个持续时间,如48小时,以及一组周日值,如星期六的星期六&。跳过这个方法来讨论下面这些类型。

这种方法的策略是将我们的持续时间例如48小时和芯片一次一天地拿走,以达到第二天开始所需的量。如果第二天恰好是禁止的星期几,我们就会滑到第二天的那一天,并继续滑动,直到达到允许的(不禁止的)星期几日期。我们继续蚕食我们的剩余时间,直到达到零。阅读代码中的评论以获得更多讨论。

计算第二天的开始时,不要假定时间为00:00:00.0。由于夏令时(DST)以及某些时区的其他异常情况,该日可能会在另一时间开始。我们呼叫atStartOfDay让java.time确定一天中的第一个时刻。

public ZonedDateTime addDurationSkippingDaysOfWeek (ZonedDateTime zdt , Duration duration , EnumSet daysOfWeek) {

// Purpose: Start at zdt, add duration but skip over entire dates where day-of-week is contained in EnumSet of prohibited days-of-week. For example, skip over United States weekend of Saturday-Sunday.

// Verify inputs.

if ((null == zdt) || (null == zdt) || (null == zdt)) {

throw new IllegalArgumentException ("Passed null argument. Message # bf186439-c4b2-423a-b5c9-76edebd87cf0.");

}

if (daysOfWeek.size() == DayOfWeek.values().length) { // We must receive 6 or less days. If passed all 7 days of the week, no days left to use for calculation.

throw new IllegalArgumentException ("The EnumSet argument specified all days of the week. Count: " + daysOfWeek.size() + ". So, impossible to calculate if we skip over all days. Message # 103a3088-5600-4d4e-a1e0-54410afa14f8.");

}

// Move through time, day-to-day, allocating remaining duration.

ZoneId zoneId = zdt.getZone(); // Passed as argument in code below.

ZonedDateTime moment = zdt; // This var is reassigned in loop below to fresh value, later and later, as we allocate the Duration to determine our target date-time.

Duration toAllocate = duration; // Loop below chips away at this Duration until none left.

while ( ! toAllocate.isZero()) { // Loop while some duration remains to be allocated.

if (toAllocate.isNegative()) { // Bad - Going negative should be impossible. Means our logic is flawed.

throw new RuntimeException ("The duration to allocate ran into a negative amount. Should not be possible. Message # 15a4267d-c16a-417e-a815-3c8f87af0232.");

}

ZonedDateTime nextDayStart = moment.toLocalDate().plusDays (1).atStartOfDay (zoneId);

Duration untilTomorrow = Duration.between (moment , nextDayStart);

// ZonedDateTime oldMoment = moment; // Debugging.

Duration allocation = null;

if (untilTomorrow.compareTo (toAllocate) >= 0) { // If getting to tomorrow exceeds our remaining duration to allocate, we are done.

// Done -- we can allocate the last of the duration. Remaining to allocate is logically zero after this step.

moment = moment.plus (toAllocate);

allocation = toAllocate; // Allocating all of our remaining duration.

// Do not exit here; do not call "return". Code below checks to see if the day-of-week of this date is prohibited.

} else { // Else more duration to allocate, so increment to next day.

moment = nextDayStart;

allocation = untilTomorrow; // Allocating the amount of time to take us to the start of tomorrow.

}

toAllocate = toAllocate.minus (allocation); // Subtract the amount of time allocated to get a fresh amount remaining to be

// Check to see if the moment has a date which happens to be a prohibited day-of-week.

while (daysOfWeek.contains (moment.getDayOfWeek())) { // If 'moment' is a date which is a day-of-week on oun prohibited list, move on to the next date.

moment = moment.toLocalDate().plusDays (1).atStartOfDay (zoneId); // Move to start of the next day after. Continue loop to check this next day.

}

}

return moment;

}

要调用该代码,我们将使用您的示例数据值。作为获取原始数据输入的一种方式,我们将一个字符串解析为LocalDateTime。

String input = "2016-01-01T18:00:00";

LocalDateTime ldt = LocalDateTime.parse (input);

这LocalDateTime对象不不代表时间轴上的实际的时刻。所以我们申请一个时区来获得一个实际的时刻,一个ZonedDateTime。

ZoneId zoneId = ZoneId.of ("America/Montreal");

ZonedDateTime zdt = ldt.atZone (zoneId);

Duration duration = Duration.ofHours (48);

我也是从“the weekend”推广到任何一组中某一天的周值,而不是硬编码的周六周日&。 java.time类包括一个方便的enum,DayOfWeek - 比我们的代码中使用字符串或数字要好得多。

在大多数语言中,Java中的enum工具比简单的数字屏蔽常量更灵活有用。其特点是当你想收集由你的枚举定义的可能项目的一个子集时,一个特殊的Set实现EnumSet。对于我们这里,我们想收集一对物品,为周六项目和周日项目。

EnumSet daysOfWeek = EnumSet.of (DayOfWeek.SATURDAY , DayOfWeek.SUNDAY);

也许工作日是四天工作制,如周一,周二加周四,周五,然后使用EnumSet.of (DayOfWeek.WEDNESDAY , DayOfWeek.SATURDAY , DayOfWeek.SUNDAY)。

现在,我们准备调用我们的计算方法。传递三个参数:

起始ZonedDateTime

一个Duration被添加到起始日期 - 时间

的DayOfWeek项目的EnumSet。

我们回到我们的计算未来的日期,时间。

ZonedDateTime zdtLater = this.addDurationSkippingDaysOfWeek (zdt , duration , daysOfWeek);

转储到控制台。

System.out.println ("zdt: " + zdt + " plus duration: " + duration + " while skipping daysOfWeek: " + daysOfWeek + " is zdtLater: " + zdtLater);

ZDT:2016-01-01T18:00-05:00 [美国/蒙特利尔]加持续时间:PT48H同时跳过daysOfWeek:[星期六,星期天]是zdtLater:2016-01-05T18:00 -05:00 [美国/蒙特利尔]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值