diff --git a/Makefile b/Makefile
index 708dbe8..c0e7cfe 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ define date_command
   fi
 endef
 commit_timestamp = "$$(${call date_command,"${COMMIT_TIMESTAMP_ISO_8601}",'+%Y%m%d%H%m.%S'})"
-commit_faketime  = "$$(${call date_command,"${COMMIT_TIMESTAMP_ISO_8601}",'+%Y-%m-%d %H:%m:%S'})"
+commit_timestamp_iso_8601 = ${COMMIT_TIMESTAMP_ISO_8601}
 
 offset_names = bytes_os_size \
                bytes_mbr_start \
@@ -222,7 +222,7 @@ ${bld}/os.iso: ${bld}/iso_files/os.zip ${bld}/iso_files/boot/iso_boot.sys ./util
 	! test -d ${bld}/iso_files.tmp
 	cp -a ${cp_T_option} -- ${bld}/iso_files ${bld}/iso_files.tmp
 	find ${bld}/iso_files.tmp -depth -exec touch -t ${commit_timestamp} '{}' ';'
-	UTILS="$$PWD/utils" (cd ./${bld}/iso_files.tmp/ && faketime -f ${commit_faketime} $$UTILS/mkisofs \
+	UTILS="$$PWD/utils" ./utils/faketime.sh ${commit_timestamp_iso_8601} sh -c '(cd ./${bld}/iso_files.tmp/ && "$$UTILS/mkisofs" \
 	 --input-charset utf-8 \
 	 -rock \
 	 -joliet \
@@ -232,7 +232,7 @@ ${bld}/os.iso: ${bld}/iso_files/os.zip ${bld}/iso_files/boot/iso_boot.sys ./util
 	 -boot-load-size 4 \
 	 -pad \
 	 -output ../os.iso \
-	 .)
+	 .)'
 	rm -- ${bld}/iso_files.tmp/os.zip \
               ${bld}/iso_files.tmp/boot/iso_boot.sys
 	rmdir ${bld}/iso_files.tmp/boot/
@@ -301,12 +301,12 @@ os_fat12_partition = "$@@@${bytes_fat12_start}"
 ${bld}/os.fat12: ${bld}/os.zip ${dep_bytes_fat12_size} ${dep_bytes_fat12_start} ${dep_sectors_os_size} \
                  ./utils/mformat ./utils/mcopy ${bld}/check_makefile
 	set -x; dd if=/dev/zero bs=${sector_size} count=${sectors_os_size} of=$@
-	faketime -f ${commit_faketime} ./utils/mformat -v "Example OS" \
+	./utils/faketime.sh ${commit_timestamp_iso_8601} ./utils/mformat -v "Example OS" \
 	 -T ${sectors_fat12_size} \
 	 -h ${os_floppy_chs_h} \
 	 -s ${os_floppy_chs_s} \
 	 -i ${os_fat12_partition}
-	faketime -f ${commit_faketime} ./utils/mcopy -i ${os_fat12_partition} $< "::os.zip"
+	./utils/faketime.sh ${commit_timestamp_iso_8601} ./utils/mcopy -i ${os_fat12_partition} $< "::os.zip"
 
 ${bld}/iso_files/os.zip: ${bld}/os.zip ${bld}/check_makefile
 # TODO: make it so that the various file formats are mutual quines:
diff --git a/utils/faketime.sh b/utils/faketime.sh
new file mode 100755
index 0000000..d36740c
--- /dev/null
+++ b/utils/faketime.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -euET -o pipefail
+
+timestamp_iso_8601="$1"
+shift
+
+date_command() {
+  # TODO: substring or case … in Darwin*)
+  if test "$(uname -s)" = Darwin; then
+    date -j -f '%Y-%m-%dT%H:%M:%S' "$(echo "${1}" | cut -c 1-19)" "${2}";
+  else
+    date -d "${1}" "${2}";
+  fi
+}
+
+if which faketime >/dev/null; then
+  ( set -x; faketime -f "$(date_command "${timestamp_iso_8601}" '+%Y-%m-%d %H:%m:%S')" "$@"; )
+elif which datefudge >/dev/null; then
+  ( set -x; datefudge --static "${timestamp_iso_8601}" "$@"; )
+else
+  echo "ERROR: command faketime or datefudge not found. Please install either command."
+  exit 1
+fi