问候,

最近,我在Nscalendar课程中遇到了一个大问题(看来)。

在我的任务中,我需要使用从公元前4000年至2000AD(Gregorian日历)开始的较大时间。在某个地方,我被迫将一些NSDATE增加100年间隔。当在AD时间轴(0-> ...)中增加年份时,一切都很好,但是当我与BC一起尝试同一件事时,我有些困惑。

问题是,当您尝试将100年增加到3000 BC [编辑]年时,无论如何您都将获得3100BC [编辑] [编辑] ...我个人觉得这很奇怪和不合逻辑。正确的结果应为2900BC。

这是您看到这种“不正确”行为的代码样本:

NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];

// initing
NSDateComponents *comps = [[[NSDateComponents alloc] init] autorelease];
[comps setYear:-1000];
NSDate *date = [gregorian dateFromComponents:comps];

// math
NSDateComponents *deltaComps = [[[NSDateComponents alloc] init] autorelease];
[deltaComps setYear:100];

date = [gregorian dateByAddingComponents:deltaComps toDate:date options:0];

// output
NSString *dateFormat = @"yyyy GG";

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:dateFormat];
NSLog(@"%@", [formatter stringFromDate:date]);

您对这种行为能说些什么?这是应该如何工作还是这是一个错误?我很困惑:S。

顺便说一句:该方法[NSCALENDAR组件:FromDate:Todate:option:]不允许我们计算BC ERA年份之间的差异...附加“为什么?”在这个潘多拉的盒子里。

PS:我正在挖掘官方文档和其他资源,但没有发现这个问题(或者它打算这样做,我是个白痴?)。

有帮助吗?

解决方案

我找到了这个错误的简单解决方法。这里是:

@interface NSCalendar (EraFixes)

- (NSDate *)dateByAddingComponentsRegardingEra:(NSDateComponents *)comps toDate:(NSDate *)date options:(NSUInteger)opts;

@end

@implementation NSCalendar (EraFixes)

- (NSDate *)dateByAddingComponentsRegardingEra:(NSDateComponents *)comps toDate:(NSDate *)date options:(NSUInteger)opts
{
    NSDateComponents *toDateComps = [self components:NSEraCalendarUnit fromDate:date];
    NSDateComponents *compsCopy = [[comps copy] autorelease];

    if ([toDateComps era] == 0) //B.C. era
    {
        if ([comps year] != NSUndefinedDateComponent) [compsCopy setYear:-[comps year]];
    }

    return [self dateByAddingComponents:compsCopy toDate:date options:opts];
}

@end

如果您想知道为什么我只倒转几年,答案很简单,除多年以外的其他组件以正确的方式增加和减少(我还没有对它们进行所有测试,但是几个月和几天似乎正常工作)。

编辑: :删除错误地添加了自动发行,谢谢约翰。

其他提示

这是一个错误和或功能。 Apple Doc从未说过他们的意思 将组件添加到日历日期. 。对于他们来说,将“添加一个组件”定义为公元前日期是年度组件的补充是完全免费的。

是的,我同意您的观点,这是违反直觉的,我认为这是一个错误。

您需要转换您的 NSDate 要点

  • 使用Unix时期的第二个(1.1.1970)使用 -timeIntervalSince1970
  • 第二个来自OS X Epoch(1.1.2001)的第二个 -timeIntervalSinceReferenceDate

然后您可以执行计算,然后将其转换回一个 NSDate. 。我认为一直在Gregorian日历上工作是一个坏主意...最好在您在GUI上展示之前转换为Gregorian日历。

想象一下您与我们时代的第一时刻约会 - 广告0001-01-01 00:00:00。 以前是什么? BC 0001-01-01 00:00:01. 。如果可可开发人员将基本算术用于此任务,您将获得 广告0000-12-31 23:59:59. 。这对于格里高利日历合理吗?我猜不会。因此,在我看来,实施日历的最方便方法是使用ERA标志,并更改”时间方向“在与卑诗省时代打交道时,在每种情况下都能获得可读的日期。

顺便提一句。: [NSCalendar dateByAddingComponents:toDate:options:] 我的举止确实很奇怪,无法计算卑诗省日期之间的时间间隔,我也检查了。因此,对于卑诗省的日期,您可以使用解决方法,例如将日期转换为AD然后找到差异。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top