library(artpipelines)
library(lubridate)
# Extract creation window
result <- verify_creation_period("path/to/artwork.procreate", verbose = TRUE)Overview
For artwork provenance and authenticity claims, we need to establish when an artwork was created. A Procreate canvas contains multiple timestamp sources that can be combined to derive a defensible creation window.
This vignette explains how verify_creation_period() extracts and validates creation timestamps to produce a forensically sound time range.
Why Creation Windows Matter
Provenance verification requires answering:
- When did the artist start this piece?
- When was it completed?
- How long did creation take?
- Is the claimed creation date consistent with the evidence?
A “defensible” creation window means the timestamps can withstand scrutiny because they come from reliable metadata sources rather than easily-modified file attributes.
Timestamp Sources in Procreate
1. Timelapse Video Segments (High Confidence)
Procreate records timelapse video in segments stored as .mp4 files. Each segment contains a mvhd (movie header) atom with a creation timestamp in QuickTime epoch (seconds since 1904-01-01 UTC).
Why high confidence: - Written by iOS/Procreate at recording time - Stored in UTC (no timezone ambiguity) - Harder to forge than file system timestamps
2. ZIP Entry Modification Times (Moderate Confidence)
The .procreate file is a ZIP archive. Each entry (layers, tiles, metadata) has a modification timestamp in the ZIP central directory.
Why moderate confidence: - Written by iOS file system - Stored in local time (requires timezone inference) - Can be modified by re-saving the canvas
3. File System Timestamps (Low Confidence)
Standard file creation/modification times from the operating system.
Why low confidence: - Easily modified - Change when file is copied - Subject to timezone issues
Basic Usage
Understanding the Results
Start Time (High Confidence)
Derived from the earliest non-empty timelapse MP4 segment:
result$start_utc
# [1] "2024-03-10 09:15:23 UTC"
result$start_confidence
# [1] "high"The start time represents when the artist first began drawing (first timelapse segment was created).
Stop Time (Moderate Confidence)
Derived from the latest tile file modification, filtered to exclude “resave windows”:
result$stop_utc
# [1] "2024-03-15 14:30:45 UTC"
result$stop_confidence
# [1] "moderate"Resave window filtering: When you re-open a Procreate file, it may update multiple file timestamps in a short burst. The function filters these out to find the actual last edit time.
Time Interval
The creation window as a lubridate::interval:
result$interval_utc
# [1] 2024-03-10 09:15:23 UTC--2024-03-15 14:30:45 UTC
# Calculate duration
time_length(result$interval_utc, "hours")
# [1] 125.26
time_length(result$interval_utc, "days")
# [1] 5.22Timezone Offset
The inferred timezone offset used to convert local times to UTC:
result$tz_offset_hours
# [1] -7
# Indicates Pacific Daylight Time (UTC-7)This is inferred by comparing MP4 creation times (UTC) with ZIP entry times (local).
Confidence Levels
Start Confidence
| Level | Source | Reliability |
|---|---|---|
high |
MP4 mvhd creation time | QuickTime epoch, UTC, hard to forge |
moderate |
ZIP entry times | Local time, requires offset inference |
low |
File system only | Easily modified, unreliable |
Stop Confidence
| Level | Source | Reliability |
|---|---|---|
high |
Multiple corroborating signals | Rare for stop time |
moderate |
Filtered tile writes | Excludes resave artifacts |
low |
Unfiltered timestamps | May include re-open artifacts |
Practical Applications
Provenance Statements
Generate a defensible provenance claim:
window <- verify_creation_period("artwork.procreate")
statement <- sprintf(
"This artwork was created between %s and %s UTC, spanning approximately %.1f hours of work.",
format(window$start_utc, "%B %d, %Y at %H:%M"),
format(window$stop_utc, "%B %d, %Y at %H:%M"),
time_length(window$interval_utc, "hours")
)
cat(statement)
# This artwork was created between March 10, 2024 at 09:15 and
# March 15, 2024 at 14:30 UTC, spanning approximately 125.3 hours of work.Validating Claimed Dates
Check if a claimed creation date falls within the verified window:
window <- verify_creation_period("artwork.procreate")
claimed_date <- as.POSIXct("2024-03-12 10:00:00", tz = "UTC")
# Is the claimed date within the creation window?
claimed_date %within% window$interval_utc
# [1] TRUE
# Is the claimed date before the verified start?
claimed_date < window$start_utc
# [1] FALSE (would indicate a problem)Detecting Anomalies
window <- verify_creation_period("artwork.procreate")
# Suspiciously short creation time for complex artwork?
if (time_length(window$interval_utc, "hours") < 1) {
warning("Creation window is very short - verify this is not a template or import")
}
# Creation allegedly in the future?
if (window$stop_utc > Sys.time()) {
warning("Stop time is in the future - check system clock or file manipulation")
}
# Very old start date?
if (window$start_utc < as.POSIXct("2018-01-01", tz = "UTC")) {
warning("Start date predates Procreate timelapse feature - verify file integrity")
}Related Functions
-
assess_procreate_canvas()- Validate canvas structure before extraction -
extract_create_date()- Simpler extraction (start time only) -
extract_creation_window()- Internal implementation
Limitations
- Requires timelapse: If timelapse recording was disabled, start confidence degrades
- Timezone inference: May be incorrect if artist traveled during creation
- Resave artifacts: Filtered but not perfectly (edge cases exist)
- File manipulation: Sophisticated forgery could defeat detection
For highest confidence, combine with: - Artist testimony - Creation progress screenshots - Social media posts during creation - Certificate of authenticity
Next Steps
- Canvas Validation - Validate canvas structure before extraction
- Advanced Workflow - Complete provenance verification workflow
- Function Reference - Complete API documentation
