FAT Timestamps on FreeDOS: Precision, Fields, and Timezone Limits
Decode FAT creation, access, and write timestamps on FreeDOS, including two-second precision, local-time ambiguity, valid ranges, and audit limits.
FAT file timestamps are compact fields in a directory entry, not modern UTC instants with a stored timezone. FreeDOS converts the system date and time into FAT’s packed representation when it creates or updates files. That design is small and compatible with DOS-era systems, but it imposes coarse precision, a limited date range, and ambiguity when disks move between machines with different clock or timezone conventions.
This article focuses on decoding and operationally interpreting the creation, last-access, and last-write fields found in FAT12, FAT16, and FAT32 short directory entries. It does not treat a displayed timestamp as forensic proof of when an event occurred. To make a defensible timeline, record the volume, operating system, timezone assumptions, clock source, copy tools, and the raw directory bytes alongside the human-readable time.
Locate the fields in a short directory entry
A standard FAT short directory entry is 32 bytes. The Microsoft FAT specification assigns these offsets:
| Offset | Size | Field | Stored precision |
|---|---|---|---|
| 0x0D | 1 byte | Creation-time subsecond value | 10 ms units within the two-second interval; FAT limits the byte to 0-199. |
| 0x0E | 2 bytes | Creation time | Packed hour, minute, and two-second count. |
| 0x10 | 2 bytes | Creation date | Packed date, years relative to 1980. |
| 0x12 | 2 bytes | Last-access date | Date only; no time-of-day field. |
| 0x16 | 2 bytes | Last-write time | Packed hour, minute, and two-second count. |
| 0x18 | 2 bytes | Last-write date | Packed date, years relative to 1980. |
The high cluster word at 0x14 has FAT32 meaning as part of the starting cluster number; it is not a timestamp. Long-filename (LFN) slots use the same 32-byte size but have the special attribute value 0x0F and do not represent ordinary file timestamp records. Deleted entries, the end-of-directory marker, volume labels, and other special entries also need to be distinguished before interpreting bytes as a normal file.
Decode the packed date and time fields
The 16-bit date stores day in bits 0-4, month in bits 5-8, and years since 1980 in bits 9-15. That yields a representable year range of 1980 through 2107. The time stores seconds divided by two in bits 0-4, minutes in bits 5-10, and hours in bits 11-15. A decoded time field therefore represents seconds 0, 2, 4, through 58; a write timestamp cannot distinguish the odd second between those values.
The creation subsecond byte is additional to the creation time field. A parser should retain it instead of discarding it, and should validate that its value is in the range defined by the specification. The last-write fields do not have that byte-level refinement. The access field stores only a date, so assigning it an invented midnight time or sorting it as though it were a full timestamp adds information that the disk never recorded.
The following host-side Python helper decodes fields after a parser has already isolated a 32-byte short entry. It deliberately does not open a disk, find a partition, or decide which timezone to apply:
from datetime import date
def fat_date(raw):
day = raw & 0x1f
month = (raw >> 5) & 0x0f
year = 1980 + ((raw >> 9) & 0x7f)
return date(year, month, day)
def fat_time(raw):
second = (raw & 0x1f) * 2
minute = (raw >> 5) & 0x3f
hour = (raw >> 11) & 0x1f
if hour > 23 or minute > 59 or second > 58:
raise ValueError('invalid packed FAT time')
return hour, minute, second
def decode_short_entry(entry):
if len(entry) != 32:
raise ValueError('expected exactly one 32-byte directory entry')
if entry[0] in (0x00, 0xe5) or entry[11] == 0x0f:
raise ValueError('not a live short-name file or directory entry')
word = lambda offset: int.from_bytes(entry[offset:offset + 2], 'little')
return {
'create_date': fat_date(word(0x10)),
'create_time': fat_time(word(0x0e)),
'create_tenths_10ms': entry[0x0d],
'access_date': fat_date(word(0x12)),
'write_date': fat_date(word(0x18)),
'write_time': fat_time(word(0x16)),
}
The date constructor rejects impossible calendar values such as month zero, day zero, or February 30. A robust forensic tool should report malformed values as malformed rather than silently normalizing them. If the target includes volume labels, directory entries, or special device metadata, add an explicit classification stage rather than assuming every live short entry is a regular file.
What FreeDOS supplies to the filesystem
The FreeDOS FAT structures define separate creation, access-date, and modification-date/time members. Its filesystem code obtains the current system date and time through the kernel’s DOS clock path when it creates entries and updates last-write values as file state changes. The directory-update path writes selected fields back to the containing directory sector and flushes buffers for the device.
This connects the value on disk to the clock presented to FreeDOS at the time of the operation. It may have originated from a hardware RTC, a virtual machine’s emulated clock, a manual DATE or TIME setting, or a tool that set timestamps through DOS services. The timestamp does not independently prove that the CMOS clock was correct. Before treating an unexpected time as a filesystem defect, compare DOS DATE and TIME, the VM clock, the host clock, and any utility that copied or preserved file metadata.
FAT has no per-entry UTC offset or daylight-saving flag in these fields. A byte-for-byte image preserves the packed values but cannot answer whether 15:30 meant local standard time, local daylight time, or a clock set to UTC. A host operating system or archive utility may display the same raw value differently after applying its own timezone policy. Explain the interpretation used in a report and preserve the raw date/time words so another analyst can reproduce it.
Creation, access, and modification are not interchangeable
The creation time is an additional FAT field and can carry finer subsecond information than last-write time. It may be rewritten by a file copy or restore program because the destination file is being newly created. Some copy tools preserve it; others create a new entry and preserve only last-write time or do not preserve timestamps at all. Verify the exact utility and options against a disposable test volume before inferring that a copy preserved every source timestamp.
Last access is only a date and may not be updated by every DOS-compatible program or storage path. Treat it as a weak clue, not an exact last-open instant. A read-only image parser, a legacy file manager, a DOS application, and a host-side FAT driver may all have different update policies. Avoid opening evidence media in a writable session if that session could change access dates or other metadata.
Last-write is the familiar modification value, but its resolution remains two seconds. If an application writes multiple times inside one interval, the stored time cannot order those writes precisely. Directory metadata and file contents can also be committed through different paths. A timestamp alone is not a proof that all file data was flushed before a failure.
The representable calendar bounds also matter during migration and archival work. A source timestamp earlier than 1980 cannot be encoded as its original date in the standard FAT date field, and a date beyond 2107 exceeds its seven-bit year range. A utility must choose a policy such as rejection, clamping, or substitution; each changes the evidence and should be recorded. Invalid month/day combinations can also appear in damaged media or in files written by defective software, so parsers should preserve the raw word even when they refuse to present a normalized calendar date.
Do not infer that FAT32 gives timestamps extra resolution simply because it has a wider cluster number. FAT12, FAT16, and FAT32 share the classic directory timestamp encoding for these fields. The filesystem subtype changes allocation and directory-layout details, not the timestamp’s timezone model or the two-second last-write granularity. Likewise, a long filename is stored through additional directory slots, but its associated short entry remains where the standard timestamp fields are defined. Inspect the valid short entry after associating its LFN slots; do not read timestamp bytes from the LFN name fragments.
A safe timeline and transfer workflow
Before touching a volume of evidentiary or operational value, make a sector-level image with a trusted tool and compute a hash of the image. Retain the source read-only and perform filesystem inspection on a copy. Record the device identity, acquisition time in UTC, the analyst host timezone, the FreeDOS or host operating-system build, and whether any mount was read-write.
For ordinary file transfer, create a small test directory containing a known file and controlled clock setting. Capture the raw entry before and after transfer using a parser that understands the volume format. Then compare:
- short-name entry bytes and LFN entries;
- decoded create, access, and write fields;
- source and destination clock/timezone assumptions;
- data hashes and file size;
- the copy utility’s documented timestamp-preservation behavior.
Do not use DATE or TIME changes to “correct” an observed FAT timestamp before preserving the original entry and image. A timezone offset or one-hour difference can be a policy mismatch, a daylight-saving interpretation, a copy-tool conversion, or a genuinely wrong clock. Change one variable in a disposable test and compare raw fields before deciding which explanation fits.
Acceptance criteria for a timestamp parser
A parser should retain raw 16-bit date and time values, creation tenths, and the entry’s attributes; reject impossible dates and times; skip LFN and deleted/end markers; distinguish access dates from full times; and state that no timezone is encoded. Test ordinary leap-day dates, the 1980 and 2107 boundaries, midnight, the maximum valid minute/second values, malformed bit patterns, and an odd-second creation time. Keep interpretation separate from byte decoding so changing the analyst’s timezone does not silently mutate the raw evidence.
FAT timestamps remain useful when treated as what they are: compact metadata with strict precision and context limits. FreeDOS’s source clarifies how its kernel obtains and persists values, while Microsoft’s specification defines the on-disk fields. A professional report states the source clock and timezone assumptions and never claims more precision than the directory entry contains.
Related:
Sources: