2010-03-22 11 views
12

que utilizan datos básicos para hacer esto:¿Cómo almacena el sistema de Data Core del iPhone SDK los tipos de fecha en 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]; 

donde el campo created_at se define como tipo "Fecha" en el xcdatamodel.

Cuando la exportación del sql de la base de datos SQLite se creó, created_at se define como tipo "marca de tiempo" y los valores se parecen:

290902422,72624

nueve dígitos antes del. y luego alguna fracción

¿Qué es este formato? No es época y no es formato julianday.

Época sería:

1269280338,81213

diajuliano sería: (. Aviso a sólo 7 dígitos antes del no 9 como si tuviera)

2.455.278,236746875

¿Cómo puedo convertir un número como 290902422.72624 para el tiempo de la época? ¡Gracias!

+0

primero, aceptar algunas respuestas ..... – KevinDTimm

+0

i cuando a través de todas las preguntas que hice y hacer clic la marca de verificación al lado de las buenas respuestas. ¿Es eso lo que quieres decir? –

+0

sí, y no te olvides de continuar. Lo que necesita hacer es aprender el formato interno de NSDate, esto no es necesariamente Apple (exactamente) sino los 'propietarios' del objetivo-C. descubre esta información y tendrás tu respuesta. – KevinDTimm

Respuesta

25

En primer lugar, tenga en cuenta que la documentación de Core Data dice que nunca debe tocar el SQL o los valores que genera por su cuenta - hacerlo puede invalidar su modelo si realiza cambios en él, y es difícil de analizar en el primer lugar.

Dicho esto, lo que puede estar viendo son fechas relativas al 1 de enero de 2001 en GMT. La documentación para NSDate especifica que el método de primitiva única, timeIntervalSinceReferenceDate, utiliza ese tiempo para su referencia. Core Data, a su vez, usa NSDateAttributeType para almacenar tipos de fecha, que se define como un objeto NSDate.

El funcionamiento de su valor a través de una calculadora produce:

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

que es aproximadamente el número de años que ha transcurrido desde que la fecha de referencia.

Si realmente necesita para analizar ese valor nuevo en una efeméride se puede utilizar el método de initWithTimeIntervalSinceReferenceDate: con su número de SQLite-almacenada para obtener una NSDate, a continuación, llamar timeIntervalSince1970 para obtener segundos época posterior (en una estructura NSTimeInterval).

+0

La respuesta de Tim alude a lo que estaba hablando, cambie su 'fecha de referencia' a 'la época' y luego guarda tus fechas de esa manera. Cuando empiece a guardar sus datos en otra plataforma, la vida será mucho más divertida después de haber realizado este cambio. – KevinDTimm

+0

@kevindtimm: dado que está utilizando Core Data, será difícil simplemente convertir arbitrariamente formatos de almacenamiento de fecha (a menos que todos los tipos de NSDate en su modelo se cambien a NSInteger, o cambie a SQLite directo). – Tim

+0

Yo recomendaría no almacenar el NSDate, en su lugar almacenar un NSDecimal del valor convertido, luego convertir de nuevo al recuperar. Pero solo si está seguro de que los datos deberán guardarse en un servidor central, donde serán manipulados por otros sistemas. – KevinDTimm

8

Me he encontrado con un problema relacionado al tratar de comparar la fecha almacenada de los Datos Centrales con la fecha almacenada de MySQL en una API remota. Mi solución fue usar las funciones de fecha de SQLite para convertir el tiempo:

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

devoluciones:

2010-03-21 22:13:42 

SQLite supone que la fecha está en la hora local y lo convierte a UTC/GMT.Si quieres que permanezca en el tiempo local, utilice el modificador hora local:

SELECT datetime('2001-01-01','+296662599 second','localtime'); 

Devuelve:

2010-03-21 17:13:42 

Esto muestra la -0500 compensado por mi TZ local.

Sobre la base de que se puede utilizar la función strftime de SQLite con el formato '% s' para obtener el tiempo época posterior:

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

Devuelve:

1269209622 

espero que esto ayude.

1

Para aquellos interesados ​​en convertir las fechas almacenadas en Core Data en Excel, se me ocurrió esta excel forumla, creo que es correcto, podría estar apagado por una hora con las cosas GMT si alguien más pudiera confirmar que sería genial

= (A1/86400) +35430,042

0

Si usted está tratando de obtener los datos directamente desde la línea de comandos SQLite, que haría

de selección de fecha y hora ('2001-01-01', dateColumn || 'segundos') de la tabla; o select datetime ('2001-01-01', dateColumn || 'seconds', 'localtime') de la tabla;

1

Aquí es un sitio web que le permite pegar los números de fecha y le muestra la fecha actual: http://blog.paddlefish.net/?page_id=90

O, aquí es cómo leer esas fechas SQLite con el rubí:

ruby -e "require 'time'; puts Time.parse('2001-01-01 00:00:00 -0000') + 123" 

Reemplazar 123 con el valor en la columna de fecha.

+0

Y aquí hay un alias para agregar a su .bashrc o .zshrc: 'alias coredatatime = 'ruby -e" require \ "time \"; pone Time.parse (\ "2001-01-01 00:00:00 -0000 \ ") + ARGV [0] .to_i" ''. Luego puede ejecutar 'coredatatime 418766400' desde la terminal. –

6

Sólo tiene que añadir 978 307 200 con el número de datos básicos y obtendrá marca de tiempo normal de

NSString *coreDataTimestamp [email protected]"464615485.832736"; //string of timestamp in coredata 
NSTimeInterval timestamp = [coreDataTimestamp doubleValue] + 978307200; 
+0

Tan simple pero genio ;-) Gracias por proporcionar el número para agregar –

Cuestiones relacionadas