Цель C NSCalendar dateFromComponents не обрабатывает неделю 53 - PullRequest
0 голосов
/ 03 января 2012

Следующий код вычисляет номер предыдущей недели из данной недели при прохождении year и week.

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:year];
[components setWeek:NSWeekCalendarUnit];
[components setWeekOfYear:(week-1)]; //Get the previous week
[components setWeekday:2]; //Monday
[components setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [calendar dateFromComponents:components];

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyyww"];
NSString *newRevision = [formatter stringFromDate:date];

Я был удивлен, что это обрабатывало случаи как 201101 (который дает 201052), но это не правильно обрабатывает годы, где есть 53 недели. Например, для 201601 он возвращает 201552 вместо 201153. (По крайней мере, он должен вернуть 201153 в соответствии с http://en.wikipedia.org/wiki/ISO_week_date в любом случае.)

Я что-то не так делаю? Я проследил, чтобы убедиться, что данные введены правильно.

Ответы [ 3 ]

2 голосов
/ 03 января 2012

Вы выбрали NSGregorianCalendar для своего календаря. Попробуйте использовать NSISO8601Calendar

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSISO8601Calendar];
1 голос
/ 05 января 2012

Мы закончили работу над этой проблемой с небольшим количеством взлома.Из ссылки на википедию в вопросе мы получили список всех лет с 53 неделями на следующие 400 лет и жестко запрограммировали их (с разумными комментариями и включенным «правильным» решением).

if (week == 1)
{
    year = year - 1;
    week = 52;
    if (year == 2004 || year == 2009 || year == 2015 || year == 2020 || year == 2026 || year == 2032 || year == 2037 || year == 2043 || year == 2048 || year == 2054 || year == 2060 || year == 2065 || year == 2071 || year == 2076 || year == 2082 || year == 2088 || year == 2093 || year == 2099 || year == 2105 || year == 2111 || year == 2116 || year == 2122 || year == 2128 || year == 2133 || year == 2139 || year == 2144 || year == 2150 || year == 2156 || year == 2161 || year == 2167 || year == 2172 || year == 2178 || year == 2184 || year == 2189 || year == 2195 || year == 2201 || year == 2207 || year == 2212 || year == 2218 || year == 2224 || year == 2229 || year == 2235 || year == 2240 || year == 2246 || year == 2252 || year == 2257 || year == 2263 || year == 2268 || year == 2274 || year == 2280 || year == 2285 || year == 2291 || year == 2296 || year == 2303 || year == 2308 || year == 2314 || year == 2320 || year == 2325 || year == 2331 || year == 2336 || year == 2342 || year == 2348 || year == 2353 || year == 2359 || year == 2364 || year == 2370 || year == 2376 || year == 2381 || year == 2387 || year == 2392 || year == 2398)
    {
        week = 53;
    }
}
else
{
    week = week-1;
}

Это не идеал, но он будет работать, пока Apple не внедрит ISO 8601 или до 2404 года.

0 голосов
/ 14 января 2016

Для случая 1 января 2016 вы должны получить:

  • неделя = 53
  • год = 2015

Когда вы печатаете свой ответиспользуйте «ГГГГ» вместо «ГГГГ».

  • ГГГГ - указывает год недели
  • гггг - указывает год даты
...