Pergunta

Eu tenho tentado encontrar uma maneira sensata de armazenar os dados diários usando Core Data no iPhone.

Meu aplicativo recebe dados em formato CSV, com uma data, mas não há tempo:

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

Quando esses dados são armazenados, deve haver apenas um registro por dia. Imaginei que a melhor coisa a fazer era criar um NSDate para ser armazenado, mas retirar os dados de fuso horário e hora.

Eu posso facilmente criar um NSDate sem horas, minutos ou segundos usando tanto NSDateComponents ou um NSDateFormatter. No entanto, mesmo quando eu definir o fuso horário explicitamente a UTC ou para zero segundos de GMT, a saída de uma data criado com NSLog () sempre tem o meu fuso horário local, como:

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

Alguém sabe de uma maneira melhor de fazer NSDates sem componentes de tempo? Ou talvez uma maneira melhor de armazenar as datas?

Foi útil?

Solução

Uma regra boa programação de ouro é sempre datas de loja em UTC. Não importa se você usar Core Data ou não; você ainda tem que fazer algum trabalho porque as classes data da Apple praticamente chupar.

As datas são representados internamente como um número de segundos desde a data de referência que é, creio eu, 01 de janeiro de 2001 00:00:00 (embora a data de referência actual não é muito importante). O ponto é, objetos NSDate são sempre nativamente no UTC. Se as datas que você está recebendo em seu arquivo CSV são locais, você precisa fazer algo assim para obter o tempo UTC:

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

Então, eu definir o tempo de 0:00:00. Agora você está salvando a data, à meia-noite, no UTC. Para fins de apresentação, você vai usar um NSDateFormatter configurado com o fuso horário de sua escolha (o fuso horário do sistema é o padrão se você não especificar um) para exibir essas datas.

Os fusos horários não realmente importa quando você está lidando apenas com datas, no entanto. Contanto que você não se esqueça de definir o fuso horário no seu NSDateFormatter a UTC, você sempre mostrar a mesma data, não importa o fuso horário que o usuário tenha selecionado em seu dispositivo.

Se você não gosta desta solução, você sempre pode armazenar as datas em um formato alternativo. Você poderia usar um double ou int para armazenar a data em algum formato personalizado (por exemplo, o número de dias desde alguma data de referência), ou você pode até rolar sua própria classe para modelar a data exatamente do jeito que você quer e armazená-lo como um NSData objeto. Enquanto os implementos classe NSCoding, você pode serializar-lo para um objeto NSData no Core Data. Você só precisa definir o tipo de atributo no Core Data para "Transformable".

Você tem uma tonelada de opções aqui, e nenhum deles envolve o esforço de escrever suas próprias consultas SQLite e bancos de dados.

Outras dicas

Um NSDate não tem um fuso horário. NSLog usa o fuso horário local; ele diz +0100 porque é onde você está.

O objeto NSDate sempre data tempo incorporar - para citar os docs que "representam [s] um único ponto no tempo" e faz isso armazenando um valor de tempo desde a sua data de referência (o início de 1 de Janeiro de 2001 GMT, de novo de acordo com os documentos). Portanto, você não pode ter um NSDate que não tem conhecimento da hora do dia.

Ao invés de tentativa e armazenar datas de sua própria maneira, eu ainda usaria NSDate no seu modelo e considere adicionar um par de métodos para a sua classe de entidade, um dos quais vai fazer o que você descreveu acima, definindo o NSDate até 00:00 : 00 em um determinado dia. O outro poderia voltar apenas a data de um NSDate em seu formato preferido. Estes, então, usar o getter Core Data-gerada e setter para acessar a propriedade NSDate.

Por ainda usando NSDate você estiver usando uma classe que Core Data pode trabalhar com nativamente, ou seja, você ainda pode usar predicados facilmente para filtrar ou classificar os resultados buscados por data sem ter que pensar muito sobre isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top