A cron job that fails writes to whatever mail was configured in 2014, and a timer’s output is in the journal alongside everything else.
# app-import.timer
[Timer]
OnCalendar=*-*-* 02:15:00
RandomizedDelaySec=300
Persistent=true
# app-import.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/import.sh
$ systemctl list-timers --all
$ journalctl -u app-import.service --since '2 days ago'
Persistent=true runs a missed occurrence at the next boot, which cron cannot do and which matters for anything on a machine that is not always on. RandomizedDelaySec is worth setting on anything running across several hosts, because a fleet hitting the same API at exactly 02:15 is a self-inflicted thundering herd. The cost is two files instead of one line, and it is the reason people keep using cron.