我的日期是自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];

(我永远不会在其他任何地方更改偏移中的任何值。)

问题是我有不同的时间 rootDate 在iOS与Mac OS X上。在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

在我的产品的先前版本中,我不在乎时间。现在我愿意。为什么在iOS上有奇怪的时间,我该怎么办? (我假设小时差为dst。)

我已经尝试将小时,分钟和第二个根组件的第二组设置为0。这没有影响。如果我将它们设置为0以外的东西,则将它们添加到8:12:28。我一直想知道这是否与LEAP秒或其他累积时钟更改有关。

还是这完全是在iOS上使用的错误方法?

有帮助吗?

解决方案 2

看起来正确的答案是使事情变得更简单。我只是每次都从组件中构建日期,而不是制作根的日期。这不应该较慢,并且仍然可以使代码真正接近这个想法。

最初设定:

self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
                    ] autorelease];
self.components = [[[NSDateComponents alloc] init] autorelease];
[components setYear: 1600];
[components setMonth: 1];

(显然,属性和ivars进行了调整。)

后来,实际将遗产日期转换为 NSDate:

[components setDay: 1 + theLegacyDate];
id eventDate = [gregorian dateFromComponents: components];

这对我有这些优势:

  1. 它用户使用了更少的IVAR。
  2. 这是较少的代码。
  3. 无论DST是否有效,它总是在那天午夜返回午夜。

其他提示

我想您对leap秒/累积时钟更改的时间是正确的。您过去与您打交道的日期是纯粹是任意时代吗?

无论哪种情况,您都可以尝试定义一个更接近当今的新时代(例如可可时代)。计算新时代和旧时期之间的一天三角洲,并将其保存为常数。当您需要处理日期时,将此三角洲应用于日期,然后使用现有的NScalendar技术,但是使用新的时代而不是旧时代。希望可以避免您看到的时钟漂移问题。

请注意,iOS考虑了各个时区的非常模糊的规则。 1月1日,很可能是午夜。 1600在您的时区实际上是在UTC的7:12:28。在许多情况下,人们抱怨日期转换中的虫子,然后有人发现他们实际上是在一个时区,这使许多年前的日历更改了。

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

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