Objective-C:查找给定日期和年份的日期

Objective-C: find date given day of the year and year

我正在为遗留数据对象编写 GUI,其中日期保存在整数属性 day of the yearyear 中(真正的 "genius" 设计...)

如何将此数据转换为给定年份的日和月?

我目前正在尝试:

int theYear = 2016;
int theDayOfTheYear = 222;
NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:theYear];
[components setDay:theDayOfTheYear];
NSDate* theDate = [gregorian dateFromComponents:components];

这对我来说似乎有点太老套了。它适用于 >31 天的天数可能只是巧合 - 在 NSDateComponents class 参考文献中没有发现任何提及。

当我调试时,po theDate 给我 2016-08-08 22:00:00 +0000 --> 关闭,但应该是 2016-08-09 (!)


要执行反向操作,即将正常的 DD-MM-YYYY 日期转换为 day of the year,我正在使用此代码:

NSDate *fullDate = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger dayOfYear = [gregorian ordinalityOfUnit:NSDayCalendarUnit
                                            inUnit:NSYearCalendarUnit
                                           forDate:fullDate];

但我似乎找不到正确的方法来做相反的事情...

有时一个测试就是全部:)

不要忘记 NSDate 是格林威治标准时间,因此您可能需要向其添加 [[NSTimeZone localTimeZone] secondsFromGMT] 秒。

看来你已经成功了:)

- (void) testDate
{
    int startYear = 2016;
    int startMonth = 1;
    int startDay = 1;

    // Create the startDate
    NSDateComponents * startDateComp = [NSDateComponents new];
    startDateComp.day = startDay;
    startDateComp.month = startMonth;
    startDateComp.year = startYear;
    NSDate * startDate = [[NSCalendar currentCalendar] dateFromComponents:startDateComp];


    for(int i=0 ; i < 365; i++)
    {
        // add i day to startDate
        NSDate * testDate = [startDate dateByAddingTimeInterval:i * 24 * 60 * 60];

        NSUInteger dayOfYear = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit
                                                                       inUnit:NSYearCalendarUnit
                                                                      forDate:testDate];

        XCTAssert(dayOfYear == (i + 1), @"the day of the year should be i + 1");

        // Create a date using day of year
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setYear:startYear];
        [components setDay:dayOfYear];
        NSDate* resultDate = [[NSCalendar currentCalendar] dateFromComponents:components];

        // testing result date against test date

        NSInteger test, result;

        test = [[NSCalendar currentCalendar] component:NSCalendarUnitDay fromDate:testDate];
        result = [[NSCalendar currentCalendar] component:NSCalendarUnitDay fromDate:resultDate];
        XCTAssert(test == result);

        test = [[NSCalendar currentCalendar] component:NSCalendarUnitMonth fromDate:testDate];
        result = [[NSCalendar currentCalendar] component:NSCalendarUnitMonth fromDate:resultDate];
        XCTAssert(test == result);

        test = [[NSCalendar currentCalendar] component:NSCalendarUnitYear fromDate:testDate];
        result = [[NSCalendar currentCalendar] component:NSCalendarUnitYear fromDate:resultDate];
        XCTAssert(test == result);

    }

请试试这个。它是更大的日历单位 NSCalendarUnitEra :)

NSDate *fullDate = [NSDate date];
NSCalendar *gregorian = [NSCalendar currentCalendar];
gregorian.timeZone =  [NSTimeZone systemTimeZone];
NSUInteger dayOfYear = [gregorian ordinalityOfUnit:NSCalendarUnitDay
                                            inUnit:NSCalendarUnitEra
                                           forDate:fullDate];

NSDateComponents *dateCom = [[NSDateComponents alloc] init];
dateCom.day = dayOfYear;

NSDate *expectedDate = [gregorian dateFromComponents:dateCom];
NSLog(@"%@",expectedDate);