Pregunta

He estado tratando de encontrar una manera sensata de almacenar datos diarios utilizando Core Data en el iPhone.

Mi aplicación recibe datos en formato csv, con una fecha pero sin hora:

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

Cuando se almacenan estos datos, solo debe haber un registro por día. Pensé que lo mejor que podía hacer era crear un NSDate para almacenar, pero eliminar el tiempo & amp; datos de zona horaria.

Puedo crear fácilmente un NSDate sin horas, minutos o segundos usando NSDateComponents o un NSDateFormatter. Sin embargo, incluso cuando configuro la zona horaria explícitamente en UTC o en cero segundos desde GMT, generar una fecha creada con NSLog () siempre tiene mi zona horaria local como:

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

¿Alguien sabe de una mejor manera de hacer NSDates sin componentes de tiempo? ¿O tal vez una mejor manera de almacenar las fechas?

¿Fue útil?

Solución

Una buena regla general de programación es almacenar siempre las fechas en UTC. No importa si usa Core Data o no; aún tendrá que hacer algo de trabajo porque las clases de citas de Apple apestan.

Las fechas se representan internamente como un número de segundos desde una fecha de referencia que es, creo, el 1 de enero de 2001 00:00:00 (aunque la fecha de referencia real no es muy importante). El punto es que los objetos NSDate siempre están de forma nativa en UTC. Si las fechas que obtiene en su archivo CSV son locales, deberá hacer algo como esto para obtener la hora UTC:

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

Entonces, establecería la hora en 00:00:00. Ahora está guardando la fecha, a la medianoche, en UTC. Para fines de presentación, utilizará un NSDateFormatter configurado con la zona horaria de su elección (la zona horaria del sistema es la predeterminada si no especifica una) para mostrar esas fechas.

Sin embargo, las zonas horarias realmente no importan cuando solo se trata de fechas. Siempre y cuando se asegure de configurar la zona horaria en su NSDateFormatter en UTC, siempre mostrará la misma fecha, sin importar la zona horaria que el usuario haya seleccionado en su dispositivo.

Si no le gusta esta solución, siempre puede almacenar sus fechas en un formato alternativo. Puede usar un double o int para almacenar la fecha en algún formato personalizado (por ejemplo, el número de días desde una fecha de referencia), o incluso puede pasar su propia clase a modele la fecha exactamente como lo desee y guárdela como un objeto NSData . Mientras la clase implemente NSCoding , puede serializarlo en un objeto NSData en Core Data. Solo necesita establecer el tipo de atributo en Core Data en " Transformable " ;.

Tiene un montón de opciones aquí, y ninguna de ellas implica el esfuerzo de escribir sus propias consultas y bases de datos SQLite.

Otros consejos

Un NSDate no tiene una zona horaria. NSLog usa su zona horaria local; dice +0100 porque ahí es donde estás.

El objeto NSDate siempre incorporará fecha y hora: para citar los documentos, "representa [s] un punto único en el tiempo". y lo hace almacenando un valor de tiempo desde su fecha de referencia (el inicio del 1 de enero de 2001 en GMT, nuevamente según los documentos). Por lo tanto, no puede tener un NSDate que desconozca la hora del día.

En lugar de tratar de almacenar fechas a su manera, todavía usaría NSDate en su modelo y consideraría agregar un par de métodos a su clase de entidad, uno de los cuales hará lo que describió anteriormente, configurando NSDate a 00:00 : 00 en un día determinado. El otro podría devolver solo la fecha de un NSDate en su formato preferido. Estos usarían el getter y setter generado por Core Data para acceder a la propiedad NSDate.

Al seguir usando NSDate, está utilizando una clase con la que Core Data puede trabajar de forma nativa, lo que significa que aún puede usar predicados fácilmente para filtrar u ordenar los resultados obtenidos por fecha sin tener que pensar demasiado en ello.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top