Как рассчитать первый NSDate текущей недели? - PullRequest
14 голосов
/ 19 августа 2010

т.е.:

  NSDate *firstDayOfWeek = [[NSDate date] firstDayOfWeek];

Например, сегодня 19 августа, я бы хотел получить NSDate из 2010-08-15 12:00am из приведенной выше строки кода.Спасибо!

Ответы [ 8 ]

36 голосов
/ 19 августа 2010

Я думаю, что эта тема соответствует тому, что вы ищете: http://www.cocoabuilder.com/archive/cocoa/211648-nsdatecomponents-question.html#211826

Обратите внимание, что понедельник не воспринимается как первые дни недели, поэтому вам, возможно, придется немного изменить его, вычтя [gregorian firstWeekday] вместо 1. Кроме того, я изменил его, чтобы использовать -currentCalendar, но это зависит от вас: -)

NSDate *today = [NSDate date];
NSCalendar *gregorian = [NSCalendar currentCalendar];

// Get the weekday component of the current date
NSDateComponents *weekdayComponents = [gregorian components:NSWeekdayCalendarUnit fromDate:today];
/*
Create a date components to represent the number of days to subtract
from the current date.
The weekday value for Sunday in the Gregorian calendar is 1, so
subtract 1 from the number
of days to subtract from the date in question.  (If today's Sunday,
subtract 0 days.)
*/
NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
/* Substract [gregorian firstWeekday] to handle first day of the week being something else than Sunday */
[componentsToSubtract setDay: - ([weekdayComponents weekday] - [gregorian firstWeekday])];
NSDate *beginningOfWeek = [gregorian dateByAddingComponents:componentsToSubtract toDate:today options:0];

/*
Optional step:
beginningOfWeek now has the same hour, minute, and second as the
original date (today).
To normalize to midnight, extract the year, month, and day components
and create a new date from those components.
*/
NSDateComponents *components = [gregorian components: (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
                                            fromDate: beginningOfWeek];
beginningOfWeek = [gregorian dateFromComponents: components];
21 голосов
/ 10 ноября 2014

Почему так сложно? :)

func firstDateOfWeekWithDate(date: NSDate) -> NSDate {

    var beginningOfWeek: NSDate?

    calendar.rangeOfUnit(.WeekOfYear, startDate: &beginningOfWeek, interval: nil, forDate: date)

    return beginningOfWeek!

}
11 голосов
/ 17 декабря 2011

Решение от naixn даст неправильные результаты, если понедельник (2) установлен на первый день недели, а проверяемая вами дата - воскресенье. В этом случае вы получите в результате понедельник следующей недели.

Правильный способ - вычислить компоненты вычитания следующим образом:

[componentsToSubtract setDay: - ((([weekdayComponents weekday] - [gregorian firstWeekday])
                                  + 7 ) % 7)];

Предполагая, что у вас всегда есть 7 дней в неделю.

2 голосов
/ 15 сентября 2015

На этот вопрос уже был дан ответ, но, как Вольфганг указал , в принятом ответе есть ошибка.Если для первого дня недели задана более высокая дата, чем для рассматриваемого NSDate, результат будет неверным.Вот полное решение, которое работает для всех возможных значений firstWeekday (в примере используется понедельник).

- (NSDate *)weekOfDate:(NSDate *)originalDate
{
    NSCalendar *currentCal = [NSCalendar currentCalendar];
    [currentCal setFirstWeekday:2]; // Sun = 1, Mon = 2, etc.

    NSDateComponents *weekdayComponents = [currentCal components:NSCalendarUnitWeekday fromDate:originalDate];

    // Calculate the number of days to subtract and create NSDateComponents with them.
    NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
    NSInteger daysToSubtract = (([weekdayComponents weekday] - [currentCal firstWeekday]) + 7) % 7;
    [componentsToSubtract setDay:-1 * daysToSubtract];

    return [currentCal dateByAddingComponents:componentsToSubtract toDate:originalDate options:0];
}
2 голосов
/ 01 июня 2013
- (NSDate *)firstDateOfWeekWithDate:(NSDate *)date {

    NSCalendar * calendar = [NSCalendar currentCalendar];

    NSDateComponents *weekdayComponents = [calendar components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:date];

    NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:date];
    [components setDay:-((([weekdayComponents weekday] - [calendar firstWeekday]) + 5 ) % 7)];

    return [calendar dateFromComponents:components];
}
1 голос
/ 19 февраля 2015

Самое простое решение:

func firstDayOfWeek(date: NSDate) -> NSDate {
  let calendar = NSCalendar.currentCalendar()
  var dateComponents = calendar.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitWeekOfMonth, fromDate: date)
  dateComponents.weekday = 1
  return calendar.dateFromComponents(dateComponents)!
}
0 голосов
/ 12 июля 2018

Для Swift 4.1:

extension Date {
  var startOfWeek: Date? {
        let calendar = Calendar(identifier: .gregorian)
        return calendar.date(from: calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
    }
}
0 голосов
/ 19 августа 2010

Используйте NSDateComponents и установите weekday в 1.

...