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

Posted

技术标签:

【中文标题】Objective-C:查找给定年份和年份的日期【英文标题】:Objective-C: find date given day of the year and year 【发布时间】:2016-08-10 08:27:18 【问题描述】:

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

在给定年份的情况下,如何将此数据转换为日和月?

我目前正在尝试:

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 类参考中没有发现任何提及。

当我调试时,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];

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

【问题讨论】:

我很惊讶它完全有效; day 组件的解释取决于日历(不清楚具体是如何工作的)。还要WRT调试输出日期;您是否考虑过 po 会以 UTC 格式打印日期/时间,而不是您当地的时区? 【参考方案1】:

有时测试就是全部:)

不要忘记 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);

    

【讨论】:

感谢弗洛里安! Duh - 忘记了时区......我似乎几乎在那里,只是调试器输出误导了我:-)仍然不确定 setDay:dayOfYear 是设计还是巧合,但通过你的测试,如果它至少被覆盖苹果永远不会改变它。【参考方案2】:

请试试这个。它是更大的日历单元 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);

【讨论】:

以上是关于Objective-C:查找给定年份和年份的日期的主要内容,如果未能解决你的问题,请参考以下文章

Redshift:提取给定星期和年份的星期六日期

Java - 在指定的给定月份 - 年份范围内打印每个月的第一个和最后一个日期

查找给定月份和年份中最后一天的名称

在php中获取给定月份和年份的开始和结束unix时间戳

在 SQL 中为给定年份设置硬编码的日期和月份

使用给定的参考年份计算给定日期的周数