【问题标题】:NSDate get next occurring weekday that is in the futureNSDate 获取未来发生的下一个工作日
【发布时间】:2015-05-08 21:50:37
【问题描述】:

我的问题的逻辑是满口的,我已经想出了一个解决方案。我的解决方案发布在下面。我正在寻找是否有人可以提出更有效/更简单的解决方案。

该方法应该返回从现在开始的下一个未来,在给定日期的工作日发生。输入日期和输出日期之间应保留时间。

对于所有示例,今天是 2015 年 5 月 8 日星期五下午 4:00: 所有输入和输出都在 2015 年:

+---------------------------+---------------------------+
|           Input           |          Output           |
+---------------------------+---------------------------+
| Tuesday April 7, 3:00 PM  | Monday May 11, 3:00 PM    |
| Thursday May 7, 3:00 PM   | Monday May 11, 3:00 PM    |
| Thursday May 7, 5:00 PM   | Friday May 8, 5:00 PM     |
| Tuesday May 12, 3:00 PM   | Wednesday May 13, 3:00 PM |
| Saturday June 20, 3:00 PM | Monday June 22, 3:00 PM   |
+---------------------------+---------------------------+

这是逻辑的一些伪代码:

do {
    date += 1 day;
} while(date.isWeekend || date.isInThePast)

这是我想出的解决方案,避免使用循环以保持效率:

- (NSDate *)nextWeekDayInFuture {
    NSDate *now = [NSDate date];
    NSDate *nextWeekDaydate;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    nextWeekDaydate = [self dateByAddingDays:1]; // custom method, adds 1 day

    if ([nextWeekDaydate isLessThan:now]) {
        NSDateComponents *nowComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:now];
        NSDateComponents *dateComponents = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:nextWeekDaydate];

        [nowComponents setHour:dateComponents.hour];
        [nowComponents setMinute:dateComponents.minute];
        [nowComponents setSecond:dateComponents.second];

        nextWeekDaydate = [calendar dateFromComponents:nowComponents];
        if ([nextWeekDaydate isLessThan:now]) {
            nextWeekDaydate = [nextWeekDaydate dateByAddingDays:1];
        }
    }

    NSDateComponents *components = [calendar components:NSCalendarUnitWeekday fromDate:nextWeekDaydate];
    if (components.weekday == Saturday) {
        nextWeekDaydate = [nextWeekDaydate dateByAddingDays:2];
    } else if (components.weekday == Sunday) {
        nextWeekDaydate = [nextWeekDaydate dateByAddingDays:1];
    }

    return nextWeekDaydate;
}

在发布解决方案之前,使用上面的输入/输出表来测试您的逻辑。

【问题讨论】:

  • 4 月 7 日星期二的输入如何给出 5 月星期一的输出?为什么不是 4 月 8 日星期三?第二行也是一样 - 为什么不是 5 月 8 日星期五
  • 请注意以下内容,“对于所有示例,今天是 2015 年 5 月 8 日星期五下午 4:00:所有输入和输出都在 2015 年:”。其中一项要求是从今天开始必须是将来的日期,返回的日期不能是过去的日期。
  • 我投票结束这个问题,因为它属于 codereview.stackexchange.com。
  • @maddy 如果您前往stackoverflow.com/help/on-topic,您可以看到它遵守主题部分。仅仅因为它也符合相关网站上的另一个主题部分,并不意味着它不符合本网站上的内容。

标签: ios objective-c algorithm date nsdate


【解决方案1】:

没有理由不将逻辑放在循环中,因为它最多会循环两次(如果当天是星期六)。

如果当前日期是周末,这里有一个解决方案:How to find weekday from today's date using NSDate?

- (NSInteger)isWeekend:(NSDate*)inDate
{
    NSCalendar* cal = [NSCalendar currentCalendar];
    NSDateComponents* comp = [cal components:kCFCalendarUnitWeekday fromDate:inDate];
    return [comp weekday];
}

然后我们可以调用这个方法,检查返回的 NSInteger 看它是 sat 还是 sun 并再次运行它:

NSDate *now = [NSDate date];
now = [now dateByAddingTimeInterval:60*60*24]; // Add 1 day's worth.

NSInteger curDay = [self isWeekend:now];

while ((curDay == 6) || (curDay == 1)) // Sat or Sund.
{
    now = [now dateByAddingTimeInterval:60*60*24]; // Add 1 day's worth.
    curDay = [self isWeekend:now];
}

如果你真的想删除循环,你可以检查它是星期六并增加 2 天,或者是太阳并增加 1 天。

NSDate *now = [NSDate date];
now = [now dateByAddingTimeInterval:60*60*24]; // Add 1 day's worth.
NSInteger curDay = [self isWeekend:now];

if (curDay == 6) // Sat
{
    now = [now dateByAddingTimeInterval:60*60*24*2]; // Add 2 day's worth.
}
else if (curDay == 1) // Sun
{
    now = [now dateByAddingTimeInterval:60*60*24]; // Add 1 day's worth.
}

【讨论】:

  • 您忽略了问题的输入。当前日期只是问题的一半。另一半是我想要下一个工作日的日期。如果我想要下一个工作日的日期是未来一个月,我希望从那里取回一个日期,而不是基于今天的日期。例如,当前日期是 2015 年 5 月 8 日星期五下午 4:00,输入是 6 月 20 日星期六下午 3:00,输出应该是 6 月 22 日星期一下午 3:00。您的算法不考虑输入,并将在 5 月 11 日星期一返回给我。
  • 这适用于任何提供的日期,我只是使用日期“现在”作为示例(NSDate *now = [NSDate date];)。你的问题表明你已经有一个未来的日期,你只是想从那个日期找出下一个工作日。用您在其他地方创建的任何 NSDate 替换我的 NSDate *now 是微不足道的。该算法不负责为问题描述和解决方案创建输入。
  • 我会尽量简化问题。有两个输入。今天的日期和传入的日期。问题是根据这些输入获取下一个工作日。这就是为什么我在原始帖子中指定今天是 2015 年 5 月 8 日星期五下午 4:00,然后我提供了一些输入,一些是过去的,一些是未来的。如果你仔细阅读问题,你会对问题有更好的理解,目前你还没有理解实际的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
相关资源
最近更新 更多