Каким образом система iPhone SDK Core Data хранит типы данных в sqlite? - PullRequest
12 голосов
/ 22 марта 2010

Я использовал основные данные для этого:

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];

Где поле create_at определено как тип "Дата" в xcdatamodel.

Когда я экспортирую sql из созданной им базы данных sqlite, созданный_ател определяется как тип «отметка времени», а значения выглядят так:

290902422,72624

Девять цифр перед. а потом немного дроби.

Что это за формат? Это не эпохальное время и не формат julianday.

Эпоха будет:

1269280338,81213

Джулиандай будет:

2455278.236746875 (заметьте только 7 цифр перед. Не 9, как у меня)

Как мне преобразовать число типа 290902422.72624 в эпоху? Спасибо!

Ответы [ 6 ]

25 голосов
/ 22 марта 2010

Во-первых, обратите внимание, что в документации Core Data говорится, что вы никогда не должны трогать SQL или значения, которые он генерирует самостоятельно - это может привести к аннулированию вашей модели, если вы внесете в нее изменения, и трудно проанализировать в первом место.

Тем не менее, вы можете видеть даты, относящиеся к 1 января 2001 года по Гринвичу. Документация для NSDate указывает, что единственный примитивный метод, timeIntervalSinceReferenceDate, использует это время для своей ссылки. Базовые данные, в свою очередь, используют NSDateAttributeType для хранения типов дат, которые определены как объект NSDate.

Запуск вашего значения через калькулятор дает:

290902422.72624 / 60 / 60 / 24 / 365.25 = 9.21814...

- это количество лет, прошедших с этой отчетной даты.

Если вам действительно нужно проанализировать это значение обратно во время эпохи, вы можете использовать метод initWithTimeIntervalSinceReferenceDate: с вашим номером, сохраненным в SQLite, чтобы получить NSDate, а затем вызвать timeIntervalSince1970, чтобы получить секунды назад (в структуре NSTimeInterval ).

8 голосов
/ 27 мая 2010

Я столкнулся с проблемой, связанной с попыткой сравнить дату, сохраненную в Core 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.

Опираясь на это, вы можете использовать функцию SQLite strftime с форматом "% s" для возврата времени эпохи:

SELECT strftime('%s',datetime('2001-01-01','+290902422.72624 second'));

Возвращает:

1269209622

Надеюсь, это поможет.

6 голосов
/ 22 сентября 2015

Просто добавьте 978307200 к числу в основных данных, и вы получите обычную временную метку

NSString *coreDataTimestamp =@"464615485.832736"; //string of timestamp in coredata
NSTimeInterval timestamp = [coreDataTimestamp doubleValue] + 978307200;
1 голос
/ 26 марта 2014

Вот веб-сайт, который позволяет вам вставлять эти цифры даты и показывает фактическую дату: 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 значением в столбце даты.

1 голос
/ 17 ноября 2010

Для тех, кто заинтересован в преобразовании дат, хранящихся в Базовых данных, в Excel, я придумал эту превосходную форумную доску, я думаю, это правильно, с часами по Гринвичу это может быть часом, если кто-то еще может подтвердить, что это было бы здорово

= (A1 / 86400) + 35430,042

0 голосов
/ 23 февраля 2011

Если вы пытаетесь получить данные непосредственно из командной строки SQLite, вы должны сделать

выбор даты и времени ('2001-01-01', dateColumn || 'секунд') из таблицы; или же выберите дату и время ('2001-01-01', dateColumn || 'секунд', 'местное время') из таблицы;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...