Как система хранения данных SDK iPhone SDK хранит типы данных в sqlite?
Я использовал основные данные для этого:
NSManagedObjectContext *m = [self managedObjectContext];
Foo *f = (Foo *)[NSEntityDescription insertNewObjectForEntityForName:@"Foo"
inManagedObjectContext:m];
f.created_at = [NSDate date];
[m insertObject:f];
NSError *error;
[m save:&error];
Если поле created_at определено как тип "Дата" в xcdatamodel.
Когда я экспортирую sql из созданной базы данных sqlite, created_at определяется как тип "timestamp", и значения выглядят следующим образом:
+290902422,72624
Девять цифр перед. а затем некоторая доля.
Что это за формат? Это не эпоха времени и это не julianday формат.
Эпоха будет:
+1269280338,81213
julianday будет:
2455278.236746875 (отметьте только 7 цифр перед. не 9, как у меня)
Как я могу преобразовать число, например 290902422.72624, в эпоху? Спасибо!
Ответы
Ответ 1
Во-первых, обратите внимание, что в документации по основным данным говорится, что вы никогда не должны прикасаться к SQL или значениям, которые генерируются сами по себе, - это может привести к аннулированию вашей модели, если вы внесете в нее изменения, и это трудно разобрать в первом место.
Таким образом, то, что вы можете видеть, относится к датам относительно 1 января 2001 года в GMT. Документация для NSDate указывает, что единственный примитивный метод timeIntervalSinceReferenceDate
использует это время для своей ссылки. Core Data, в свою очередь, использует NSDateAttributeType
для хранения типов дат, которые определены как объект NSDate.
Запуск вашего значения с помощью калькулятора дает:
290902422.72624 / 60 / 60 / 24 / 365.25 = 9.21814...
который относится к числу лет, прошедших с этой контрольной даты.
Если вам действительно нужно проанализировать это значение в эпоху, вы можете использовать метод initWithTimeIntervalSinceReferenceDate:
со своим SQLite-сохраненным номером, чтобы получить NSDate, а затем вызовите timeIntervalSince1970
, чтобы вернуть эпоху назад (в структуре NSTimeInterval).
Ответ 2
У меня возникла проблема, связанная с попыткой сравнить дату, сохраненную в Data Data, с MySQL, хранящейся в удаленном API. Моим решением было использовать функции даты SQLite для преобразования времени:
SELECT datetime('2001-01-01','+290902422.72624 second');
Возврат:
2010-03-21 22:13:42
SQLite предполагает, что дата указана по местному времени и преобразует ее в UTC/GMT. Если вы хотите, чтобы он оставался в локальное время, используйте локальный модификатор времени:
SELECT datetime('2001-01-01','+296662599 second','localtime');
Возврат:
2010-03-21 17:13:42
Это показывает смещение -0500 для моего локального TZ.
Основываясь на этом, вы можете использовать функцию strftime SQLite с форматом "% s", чтобы вернуть время:
SELECT strftime('%s',datetime('2001-01-01','+290902422.72624 second'));
Возврат:
1269209622
Надеюсь, это поможет.
Ответ 3
Просто добавьте 978307200 к числу в основных данных, и вы получите нормальную метку времени
NSString *coreDataTimestamp [email protected]"464615485.832736"; //string of timestamp in coredata
NSTimeInterval timestamp = [coreDataTimestamp doubleValue] + 978307200;
Ответ 4
Для тех, кто заинтересован в преобразовании дат, хранящихся в Core Data, в Excel, я придумал этот excel forumla, я думаю, что это правильно, возможно, он отключится на час с материалами GMT, если кто-то еще сможет подтвердить, что это будет классно
= (A1/86400) +35430.042
Ответ 5
Вот веб-сайт, который позволяет вставлять эти цифры и показывает фактическую дату: http://blog.paddlefish.net/?page_id=90
Или, здесь, как читать эти даты sqlite с ruby:
ruby -e "require 'time'; puts Time.parse('2001-01-01 00:00:00 -0000') + 123"
Замените 123
на значение в столбце даты.
Ответ 6
Если вы пытаетесь получить данные непосредственно из командной строки SQLite, вы бы сделали
выберите datetime ('2001-01-01', dateColumn || 'seconds') из таблицы;
или
выберите datetime ('2001-01-01', dateColumn || 'seconds', 'localtime') из таблицы;