¿Qué formato usa la fecha de sqlite db de Apple Notes?

Quiero extraer los textos de las notas y las fechas de modificación de una base de datos de notas sqlite extraída de una copia de seguridad del dispositivo iOS. Pero no puedo entender cómo convertir el formato de fecha en una cadena de fecha legible.

como obtuve los datos

Descubrí qué archivo tenía los datos de la nota de esta página .

Porción relevante:

Step 1. Find the Backup File in ~/Library/Application Support/MobileSync/Backup/fea….627
        something like : ca3b….39c
       If you have trouble seeing Library folder 
       defaults write com.apple.Finder AppleShowAllFiles Yes
Step 2. Copy file and rename as notes.sqlite 

Lo que he probado hasta ahora

Abrí el archivo y confirmé que contiene el texto del cuerpo de la nota esperado. El cuerpo del texto está dentro de una tabla llamada ZNOTEBODY. Otra tabla llamada ZNOTEtiene una ZBODYcolumna que parece contener índices en la ZNOTEBODYtabla y una ZMODIFICATIONDATEcolumna. Aquí está el quid de la cuestión: la ZMODIFICATIONDATEcolumna tiene un tipo de lista TIMESTAMPy contiene números de coma flotante.

Miré los documentos de sqlite y encontré esto:

SQLite no tiene una clase de almacenamiento reservada para almacenar fechas y/u horas. En cambio, las funciones integradas de fecha y hora de SQLite son capaces de almacenar fechas y horas como valores de TEXTO, REAL o ENTERO:

  • TEXTO como cadenas ISO8601 ("YYYY-MM-DD HH:MM:SS.SSS").
  • REAL como números de días julianos, el número de días desde el mediodía en Greenwich el 24 de noviembre de 4714 aC según el calendario gregoriano proléptico.
  • INTEGER como Unix Time, el número de segundos desde 1970-01-01 00:00:00 UTC.

Las aplicaciones pueden optar por almacenar fechas y horas en cualquiera de estos formatos y convertir libremente entre formatos utilizando las funciones de fecha y hora integradas.

Así que intenté usar la función incorporada datetimecon un simple SELECT datetime(ZMODIFICATIONDATE) FROM ZNOTE;pero que produjo valores sin sentido como 1171380-13689427-18 21:08:40para una entrada que sé que corresponde a 2014-08-12. El valor almacenado en cuestión era 429559087.38102.

Entonces, ¿alguien sabe qué formato se está usando aquí? O, más importante aún, ¿cómo convertirlo en una fecha legible?

Las siguientes fechas almacenadas corresponden a (puntos diferentes en) 2014-08-11, en orden de la más antigua a la más reciente.

  • 429435093.400244
  • 429446655.298724
  • 429447111.140259
  • 429460783.273032
  • 429464301.184442

(No estaba seguro de dónde publicar esto, pero como parece que podría ser específico de Apple, este parecía ser el mejor lugar).

Respuestas (1)

De acuerdo con esta respuesta en Stack Overflow, es una marca de tiempo de Unix ajustada por 31 años. Esto es típico de CoreData, el marco ORM de Apple. Lo siguiente funcionaría:

select datetime(zmodificationdate,'unixepoch','31 years') from znote
Para otros que vienen aquí en busca de consejos sobre cómo interpretar las fechas almacenadas en sqlite por las aplicaciones de iOS: algunas aplicaciones (estúpidamente) guardan las marcas de tiempo como hora local en lugar de UTC; en ese caso, debe agregar un 'localtime'parámetro a esa datetimellamada, por ejemplo datetime(foo, 'unixepoch', '31 years', 'localtime'), particularmente complicado para los usuarios del Reino Unido (digamos) donde localtime == UTC durante la mitad del año pero no la otra mitad.