0

I have a coredata model backed by a sqllite db. I want to populate the db with some initial data.

I have been using Python to do this so far and it has been working well. The only bit that isn't working is inserting dates. I understand coredata stores dates in epoch format so I am currently inserting them via Python like this:

time.mktime(datetime(2012, 7, 1, 12, 30, 30).timetuple())

However, this doesn't give me the correct date when the data is loaded via coredata. Any ideas on how to format the date so it is read in correctly via coredata?

*NOTE: I realise that most people recommend doing this via a small app that uses the same model rather than using a Python script, but I find the Python syntax more concise for constructing and inserting lots of objects.

E.g. I can call methods that insert data like this:

insertData(con, 1, 1, 'Data 1', 'Description')

vs Objective-C with its long-winded method calls:

[self insertdata withCon:con id: 1 i2:1 val:@"Data 1", Desc:@"Description"];
AndyG
  • 39,700
  • 8
  • 109
  • 143
Imran
  • 1,488
  • 1
  • 15
  • 36
  • Check http://stackoverflow.com/questions/10705062/behind-the-scenes-core-data-dates-stored-with-31-year-offset and see if that helps – Jon Clements Jul 07 '12 at 13:45
  • I can do this: nsdate = dateCompleted - datetime(2001, 1, 1, 0, 0, 0) but then how to I convert this to something I can insert in to the sqlite timestamp column? This is the first time I am using python. – Imran Jul 07 '12 at 14:39
  • Ray Wenderlich has written a nice tutorial about how to do that. Refer [his blog](http://www.raywenderlich.com/980/core-data-tutorial-how-to-preloadimport-existing-data) – Salil Jul 08 '12 at 13:09

2 Answers2

2

Core Data appears to use 1 January 2001, GMT as the reference date (same as the NSDate method timeIntervalSinceReferenceDate) and not 1970, as the mktime function in Python, so you'd have to calculate your timestamp based on that.

This is entirely undocumented of course, and I'd agree with dpjanes' answer that this approach is generally a bad idea.

If you really really want to do this, you could construct an appropriate timestamp in Python like this:

import time
from datetime import datetime

ref = time.mktime(datetime(2001, 1, 1, 0, 0, 0).timetuple())
now = time.time() - ref
Community
  • 1
  • 1
omz
  • 53,243
  • 5
  • 129
  • 141
  • And make sure the sqlite3 datetime column is declared as INTEGER as per section 1.2 here (http://www.sqlite.org/datatype3.html) – dpjanes Jul 08 '12 at 11:41
  • One would assume anyway! There's no rule that says CoreData has to implement datetime the way sqlite wants. – dpjanes Jul 08 '12 at 11:51
  • Though it doesn't really matter because SQLite uses dynamic column types, I think that a `REAL` would be more appropriate, as timestamps are `double`s in Cocoa. – omz Jul 08 '12 at 11:52
  • So I got this working, thanks for the input guys. Doing a simple date - refdate gives a timedelta which my script complains about when I try to insert in to the timestamp column. If i call total_seconds() on this though it goes in fine and is correctly read in coredata without me having to mess with the db schema. – Imran Jul 09 '12 at 13:29
1

Alas, don't do this. I use Python all the time to populate sqlite databases and read them with Objective-C and Java, but CoreData is something that uses sqlite but how it uses it may change over time.

Because Core Data is not intended to be an ORM for sqlite, it cannot read arbitrary sqlite schema. Conversely, you should not rely on being able to read Core Data's sqlite data stores with other sqlite tools; the schema is an implementation detail that may change.

From https://stackoverflow.com/a/524301/96338

Community
  • 1
  • 1
dpjanes
  • 5,745
  • 3
  • 25
  • 30
  • Yup I realise that as i said in my post. I am open to suggestions on alternatives that dont involve writing object construction in objective c which i find cumbersome and to explicit for this kind of thing. – Imran Jul 09 '12 at 13:28