Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa touch 从1600年至今?_Cocoa Touch_Ios_Nsdate_Nscalendar_Nsdatecomponents - Fatal编程技术网

Cocoa touch 从1600年至今?

Cocoa touch 从1600年至今?,cocoa-touch,ios,nsdate,nscalendar,nsdatecomponents,Cocoa Touch,Ios,Nsdate,Nscalendar,Nsdatecomponents,我有一个日期,从1600年1月1日起以天数的形式存储,我需要处理它。这是一种传统的日期格式,我需要在应用程序中多次阅读 以前,我一直在创建日历、空日期组件和根日期,如下所示: self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar ] autorelease]; id rootComponents = [[[NSDateComponents

我有一个日期,从1600年1月1日起以天数的形式存储,我需要处理它。这是一种传统的日期格式,我需要在应用程序中多次阅读

以前,我一直在创建日历、空日期组件和根日期,如下所示:

self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
                    ] autorelease];
id rootComponents = [[[NSDateComponents alloc] init] autorelease];
[rootComponents setYear: 1600];
[rootComponents setMonth: 1];
[rootComponents setDay: 1];
self.rootDate = [gregorian dateFromComponents: rootComponents];
self.offset = [[[NSDateComponents alloc] init] autorelease];
然后,为了稍后将整数转换为日期,我使用以下方法:

[offset setDay: theLegacyDate];
id eventDate = [gregorian dateByAddingComponents: offset
                                          toDate: rootDate
                                         options: 0];
(我从不在任何其他位置更改偏移中的任何值。)

问题是我在iOS和Mac OS X上获得的
rootDate
时间不同。在Mac OS X上,我得到的是午夜。在iOS上,我得到8:12:28。(到目前为止,这似乎是一致的。)当我加上我的天数后,奇怪的时间仍然存在

OS | legacyDate | rootDate | eventDate ======== | ========== | ==========================|========================== Mac OS X | 143671 | 1600-01-01 00:00:00 -0800 | 1993-05-11 00:00:00 -0700 iOS | 143671 | 1600-01-01 08:12:28 +0000 | 1993-05-11 07:12:28 +0000 OS | legacyDate | rootDate | eventDate ======== | ========== | ==========================|========================== Mac OS X | 143671 | 1600-01-01 00:00:00-0800 | 1993-05-11 00:00:00-0700 iOS | 143671 | 1600-01-0108:12:28+0000 | 1993-05-1107:12:28+0000 在我之前发布的产品中,我不在乎时间;现在我知道了。为什么iOS上会出现这种奇怪的时间,我该怎么办?(我假设时差为DST。)

我已尝试将rootComponents的小时、分钟和秒设置为0。这没有影响。如果我将它们设置为0以外的值,则会将它们添加到8:12:28。我一直在想这是否与闰秒或其他累积时钟变化有关


或者这是在iOS上使用的完全错误的方法吗?

我想你关于闰秒/累计时钟变化对时间问题的解释是正确的。你正在处理的日期实际上是在过去,还是纯粹是一个任意的时代


在任何一种情况下,你都可以尝试定义一个更接近今天的新纪元(比如可可纪元)。计算新纪元和旧纪元之间的日增量,并将其保存为常量。当您需要处理日期时,将此增量应用于该日期,然后使用现有的NSCalendar技术,但使用新纪元而不是旧纪元。这将有望避免您所看到的时钟漂移问题。

我想您关于闰秒/累计时钟变化对时间问题的解释是正确的。你正在处理的日期实际上是在过去,还是纯粹是一个任意的时代


在任何一种情况下,你都可以尝试定义一个更接近今天的新纪元(比如可可纪元)。计算新纪元和旧纪元之间的日增量,并将其保存为常量。当您需要处理日期时,将此增量应用于该日期,然后使用现有的NSCalendar技术,但使用新纪元而不是旧纪元。这将有望避免您看到的时钟漂移问题。

看来正确的答案是让事情变得更简单。我每次都只是从组件构建日期,而不是创建rootDate。这应该不会太慢,而且仍然可以让代码真正接近想法

初始设置:

self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
                    ] autorelease];
self.components = [[[NSDateComponents alloc] init] autorelease];
[components setYear: 1600];
[components setMonth: 1];
(显然,属性和IVAR已调整。)

稍后,要将传统日期实际转换为
NSDate

[components setDay: 1 + theLegacyDate];
id eventDate = [gregorian dateFromComponents: components];
这对我来说有以下好处:

  • 它使用更少的IVAR
  • 它的代码更少
  • 无论DST是否生效,它总是在当天午夜返回

  • 看来正确的答案是让事情变得更简单。我每次都只是从组件构建日期,而不是创建rootDate。这应该不会太慢,而且仍然可以让代码真正接近想法

    初始设置:

    self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
                        ] autorelease];
    self.components = [[[NSDateComponents alloc] init] autorelease];
    [components setYear: 1600];
    [components setMonth: 1];
    
    (显然,属性和IVAR已调整。)

    稍后,要将传统日期实际转换为
    NSDate

    [components setDay: 1 + theLegacyDate];
    id eventDate = [gregorian dateFromComponents: components];
    
    这对我来说有以下好处:

  • 它使用更少的IVAR
  • 它的代码更少
  • 无论DST是否生效,它总是在当天午夜返回

  • 请注意,iOS考虑了不同时区的非常模糊的规则。很可能是1月1日午夜。你所在时区的1600实际上是协调世界时7:12:28。在很多情况下,人们抱怨日期转换中存在错误,然后有人发现他们所在的时区在多年前进行了一些奇怪的日历更改


    您需要首先找出数据所代表的确切日期。“1600年1月1日以来的天数”是胡说八道,因为你需要一个时区!你应该做什么:找到一个“遗产”号码,你知道它应该代表哪一天。例如,如果您“知道”143671应该是您所在时区的1993年5月11日,则从该日期开始作为根日期,并向其添加(x-143671)天

    请注意,iOS考虑了不同时区的非常模糊的规则。很可能是1月1日午夜。你所在时区的1600实际上是协调世界时7:12:28。在很多情况下,人们抱怨日期转换中存在错误,然后有人发现他们所在的时区在多年前进行了一些奇怪的日历更改


    您需要首先找出数据所代表的确切日期。“1600年1月1日以来的天数”是胡说八道,因为你需要一个时区!你应该做什么:找到一个“遗产”号码,你知道它应该代表哪一天。例如,如果您“知道”143671应该是您所在时区的1993年5月11日,则从该日期开始作为根日期,并向其添加(x-143671)天

    这是一个好主意,但不幸的是它仍然会留下+/-1小时的误差。这是一个好主意,但不幸的是它仍然会留下+/-1小时的误差。