如何在核心数据中存储没有时间的日期

发布于 2024-07-30 00:00:32 字数 524 浏览 0 评论 0原文

我一直在尝试找到一种在 iPhone 上使用 Core Data 存储日常数据的合理方法。

我的应用程序接收 csv 格式的数据,有日期但没有时间:

date, cycles
2009-08-01, 123
2009-08-02, 234
2009-08-03, 345
2009-08-04, 456

存储此数据时,每天应该只有一条记录。 我认为最好的办法是创建一个 NSDate 来存储,但去掉时间和时间。 时区数据。

我可以使用 NSDateComponents 或 NSDateFormatter 轻松创建 NSDate,无需几小时、几分钟或几秒。 然而,即使我将时区明确设置为 UTC 或从 GMT 算起的零秒,使用 NSLog() 输出创建的日期总是有我的本地时区,例如:

2009-07-29 00:00:00 +0100

有谁知道更好的方法来制作 NSDates没有时间成分? 或者也许是存储日期的更好方法?

I've been trying to find a sensible way of storing daily data using Core Data on the iPhone.

My app receives data in csv format, with a date but no time:

date, cycles
2009-08-01, 123
2009-08-02, 234
2009-08-03, 345
2009-08-04, 456

When this data is stored, there should only be one record per day. I figured the best thing to do was create an NSDate to be stored, but strip out the time & time zone data.

I can easily create an NSDate without hours, minutes or seconds using either NSDateComponents or an NSDateFormatter. However even when I set the time zone explicitly to UTC or to zero seconds from GMT, outputting a created date with NSLog() always has my local timezone like:

2009-07-29 00:00:00 +0100

Does anyone know of a better way to make NSDates without time components? Or perhaps a better way of storing the dates?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

独自←快乐 2024-08-06 00:00:32

一个好的编程经验法则是始终以 UTC 格式存储日期。 是否使用 Core Data 并不重要; 你仍然需要做一些工作,因为苹果的日期类非常糟糕。

日期在内部表示为自参考日期(我认为是 2001 年 1 月 1 日 00:00:00)以来的秒数(尽管实际的参考日期并不是很重要)。 要点是,NSDate 对象本身始终采用 UTC。 如果您在 CSV 文件中获取的日期是本地日期,则需要执行类似以下操作来获取 UTC 时间:

NSDate *UTCDate = [localDate addTimeInterval:-[[NSTimeZone localTimeZone] secondsFromGMT]];

然后,我将时间设置为 00:00:00。 现在您将在午夜以 UTC 格式保存日期。 出于演示目的,您将使用配置了您选择的时区的 NSDateFormatter(如果您未指定时区,则系统时区是默认值)来显示这些日期。

不过,当您只处理日期时,时区并不重要。 只要您确保将 NSDateFormatter 上的时区设置为 UTC,无论用户在设备上选择哪个时区,您都将始终显示相同的日期。

如果您不喜欢此解决方案,您可以随时以其他格式存储日期。 您可以使用 double 或 int 以某种自定义格式存储日期(例如,自某个参考日期以来的天数),或者您甚至可以将自己的类滚动到完全按照您想要的方式对日期进行建模并将其存储为 NSData 对象。 只要类实现了 NSCoding,就可以将其序列化为 Core Data 中的 NSData 对象。 您只需将Core Data中的属性类型设置为“Transformable”即可。

这里有很多选择,但没有一个需要编写自己的 SQLite 查询和数据库。

A good programming rule of thumb is to always store dates in UTC. It doesn't matter whether you use Core Data or not; you'll still have to do some work because Apple's date classes pretty much suck.

Dates are represented internally as a number of seconds since a reference date which is, I believe, 1 January 2001 00:00:00 (although the actual reference date isn't very important). Point is, NSDate objects are always natively in UTC. If the dates you're getting in your CSV file are local, you'll need to do something like this to get the UTC time:

NSDate *UTCDate = [localDate addTimeInterval:-[[NSTimeZone localTimeZone] secondsFromGMT]];

Then, I'd set the time to 00:00:00. Now you're saving the date, at midnight, in UTC. For presentation purposes, you will use an NSDateFormatter configured with the time zone of your choice (the system time zone is the default if you don't specify one) to display those dates.

Time zones don't really matter when you're just dealing with dates, though. As long as you make sure to set the time zone on your NSDateFormatter to UTC, you'll always show the same date, no matter what time zone the user has selected on her device.

If you don't like this solution, you can always store your dates in an alternative format. You could use a double or int to store the date in some custom format (e.g. the number of days since some reference date), or you could even roll your own class to model the date exactly the way you want and store it as an NSData object. As long as the class implements NSCoding, you can serialize it to an NSData object in Core Data. You just need to set the attribute type in Core Data to "Transformable".

You have a ton of options here, and none of them involve the effort of writing your own SQLite queries and databases.

人间☆小暴躁 2024-08-06 00:00:32

NSDate 没有时区。 NSLog 使用您当地的时区; 它显示+0100,因为那就是你所在的位置。

An NSDate doesn't have a time zone. NSLog uses your local time zone; it says +0100 because that's where you are.

恬淡成诗 2024-08-06 00:00:32

NSDate 对象将始终包含时间日期 - 引用文档,它“代表单个时间点”,并通过存储自其参考日期(格林尼治标准时间 2001 年 1 月 1 日开始,同样根据文档)。 因此,您不能拥有不知道一天中的时间的 NSDate。

我仍然会在模型中使用 NSDate 并考虑向实体类添加一对方法,而不是尝试以自己的方式存储日期,其中一个方法将执行上面描述的操作,将 NSDate 设置为 00:00:00某一天。 另一个可以仅以您喜欢的格式返回 NSDate 中的日期。 然后,它们将使用 Core Data 生成的 getter 和 setter 来访问 NSDate 属性。

通过仍然使用 NSDate,您将使用 Core Data 可以在本机使用的类,这意味着您仍然可以轻松使用谓词进行过滤,或者按日期对获取的结果进行排序,而不必考虑太多。

The NSDate object will always incorporate time date - to quote the docs it "represent[s] a single point in time" and does so by storing a time value since its reference date (the start of 1 January 2001 at GMT, again according to the docs). Therefore you cannot have an NSDate that is unaware of time of day.

Rather than try and store dates your own way, I would still use NSDate in your model and consider adding a pair of methods to your entity class, one of which will do what you described above, setting the NSDate to 00:00:00 on a given day. The other could return just the date from an NSDate in your preferred format. These would then use the Core Data-generated getter and setter to access the NSDate property.

By still using NSDate you are using a class that Core Data can work with natively, meaning you can still use predicates easily for filtering, or sort your fetched results by date without having to think too hard about it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文