Core Data Timestamp Converter
Convert a Core Data timestamp — seconds since January 1, 2001 UTC — to a Unix timestamp, ISO 8601, and a readable date. Core Data stores dates using Apple’s CFAbsoluteTime reference date.
What is a Core Data timestamp?
Apple’s Core Data framework stores Date attributes as the number of seconds since January 1, 2001 00:00:00 UTC — the same CFAbsoluteTime reference date used across macOS and iOS. When you open a Core Data store directly in SQLite, date columns (often named Z…DATE) appear as these 2001-based floating-point values.
- Epoch: 2001-01-01 00:00:00 UTC
- Type: floating-point seconds (sub-second precision preserved)
- Seen in: Core Data SQLite stores, ZDATE / Z_…_DATE columns, exported .sqlite databases
- Identical reference date to NSDate timeIntervalSinceReferenceDate
How to convert a Core Data timestamp to Unix time
Add the 978,307,200-second gap between 1970 and 2001 to rebase a Core Data value onto the Unix epoch.
- Unix seconds = CoreDataTimestamp + 978307200
- Example: 721692800 → 1700000000 → 2023-11-14 22:13:20 UTC
- SQLite: datetime(ZDATE + 978307200, "unixepoch")
- Reverse: CoreDataTimestamp = Unix seconds − 978307200
Querying Core Data SQLite stores
Reading a Core Data database directly is common in forensics and debugging. Because the values are 2001-based, a forgotten offset shifts every date ~31 years into the past. Negative values are valid and represent dates before 2001.
- Column names are usually prefixed with Z (Core Data’s internal naming)
- A value of 0 means 2001-01-01, frequently used as a default/unset date
- Times are stored in UTC; apply the display timezone afterward
- What epoch does Core Data use?
- Core Data stores dates as seconds since January 1, 2001 00:00:00 UTC, the same reference date as CFAbsoluteTime/NSDate.
- How do I convert a Core Data ZDATE to a real date?
- Add 978,307,200 to the value to get a Unix timestamp, then format it — for example, SQLite datetime(ZDATE + 978307200, "unixepoch").
- Why are my Core Data dates 31 years off?
- You likely treated the 2001-based value as a Unix timestamp. Add the 978,307,200-second offset to correct it.