EZ LearnEZ Learn
Courses
EZ Board
Dashboard
All articles
python-for-cyber-securitypythondigital-forensicstimeline

Converting Timestamps and Building a Timeline

Twenty CCTV cameras are useless if their clocks disagree. Chrome counts time in microseconds since 1601, not 1970, and getting that conversion wrong puts your timeline centuries off.

Ashish Revar17 October 20267 min read1 views
1 video lesson 6:09 total
Sign in to track your progress

Video lesson

The last article's last_visit_time from Chrome's history database was a plain integer, nothing like the readable timestamps os.stat returned. That is not an accident; it is a trap almost every beginner walks into once, and it is where this article starts.

Analogy: The CCTV control room

A security office watching twenty CCTV cameras can only reconstruct what happened if every camera's clock agrees. If one runs three minutes fast and another shows the wrong time zone, the footage cannot be lined up into a single story. Digital evidence has the same problem at a larger scale: almost every operating system and application stores timestamps in its own format and its own reference. A forensic timeline is only useful once every timestamp has been converted to one common, unambiguous reference, usually UTC.

A real browser's trap: 1601, not 1970

Browsers are a classic trap: Chrome stores a timestamp as the number of microseconds since 1 January 1601, not the Unix reference of 1970. Comparing the two without converting first produces a timeline that is wrong by centuries.

convert_chrome_time.py

# convert_chrome_time.py
import datetime

def chrome_time_to_datetime(chrome_timestamp):
    """Chrome timestamps are microseconds since 1601-01-01."""
    epoch_start = datetime.datetime(1601, 1, 1)
    return epoch_start + datetime.timedelta(microseconds=chrome_timestamp)

print(chrome_time_to_datetime(13350274993000000).isoformat())

Sample output

2024-01-21T01:43:13

Python concept: Why 1601 of all years

1601 is the start of the first full 400-year Gregorian calendar cycle, which makes the arithmetic for leap years land on clean boundaries. Chrome inherited this reference from Windows' own internal file-time format, which chose it for the same reason. The number itself has no deeper significance beyond that convenience; what matters for a script is simply getting the reference date right.

The function adds a timedelta built from microseconds directly onto that 1601 starting point, which Python's datetime handles correctly no matter how large the number is. Converting the other direction, from an ordinary date into a Chrome timestamp, is the same arithmetic run backwards:

datetime_to_chrome.py

import datetime

def datetime_to_chrome(dt):
    epoch_start = datetime.datetime(1601, 1, 1)
    return int((dt - epoch_start).total_seconds() * 1_000_000)

ts = datetime_to_chrome(datetime.datetime(2026, 10, 17, 14, 2, 11))
print(ts)
print(chrome_time_to_datetime(ts).isoformat())   # round trip, back to the original

Sample output

13436719331000000
2026-10-17T14:02:11

The round trip returns exactly the date that went in, which is the simplest way to confirm a timestamp conversion is correct before trusting it with real evidence.

Building one timeline from many sources

With every timestamp normalised to the same reference, a timeline is a matter of collecting events from every source into one list and sorting it.

File times (MACB)Browser (SQLite)Log files (syslog)Normalise to UTCOne sorted timeline
Figure 3.3. Timeline reconstruction: gather events from many sources, convert every timestamp to one reference, and sort. The sorted result is the forensic story.

build_timeline.py

# build_timeline.py
from file_times import get_macb_times
from convert_chrome_time import chrome_time_to_datetime

timeline_events = []

def add_event(source, description, event_time):
    timeline_events.append(
        {"time": event_time, "source": source, "description": description}
    )

add_event("filesystem", "report.pdf modified", get_macb_times("evidence_copy/report.pdf")["modified"])
add_event("browser", "Visited cybercrime.gov.in", chrome_time_to_datetime(13436719184000000))
add_event("browser", "Visited example.com", chrome_time_to_datetime(13436719331000000))

timeline_events.sort(key=lambda e: e["time"])
for event in timeline_events:
    print(f"{event['time'].isoformat()}  [{event['source']}]  {event['description']}")

Sample output

2026-10-17T13:59:44  [browser]  Visited cybercrime.gov.in
2026-10-17T14:02:11  [browser]  Visited example.com
2026-10-17T20:01:23.018310  [filesystem]  report.pdf modified

add_event() does almost nothing, which is the point: it only ever receives an already-converted Python datetime, never a raw platform-specific number, so the sort at the end, timeline_events.sort(key=lambda e: e["time"]), compares like with like across every source without caring which format each one started in.

A sorted, multi-source timeline is often what turns a pile of individually unremarkable facts, a file was edited, a page was visited, a login occurred, into a coherent account of what happened and in what order, which is usually the real deliverable an investigation is asked to produce.

Case study: Reading the timeline above

Two web pages were visited within three minutes of each other, and a PDF was modified nearly six hours later. On its own, each fact is unremarkable. Placed on one sorted timeline, a reader can ask a sharper question: was the PDF modified after the cybercrime portal was visited, by the same person, as part of filing a report, or is the gap long enough that they are unrelated? The timeline does not answer that question by itself; it is what makes the question askable in the first place.

Check your understanding

Question 1: Using the CCTV analogy, explain why a Chrome history timestamp cannot be compared directly with a Unix file-modification timestamp.

Twenty CCTV cameras only tell one story if every camera's clock agrees; otherwise the footage cannot be lined up. Chrome counts microseconds from 1601, while a Unix file-modification time counts seconds from 1970. Comparing the raw numbers directly is like comparing two cameras with clocks set to different years: the numbers are both valid, but not to the same reference, so a naive comparison would be wrong by centuries.

Question 2: What does add_event() deliberately not do, and why does that matter for the final sort?

It never converts a timestamp itself; it only accepts one that has already been converted to an ordinary Python datetime. That matters because the final sort compares every event's time directly, and that only works correctly if every time passed in already shares the same reference before it arrives.

Question 3: Why is a round trip, converting a date to a Chrome timestamp and back again, a useful way to check a conversion function?

If the function is correct, the date that comes out at the end should exactly match the date that went in. A mismatch immediately reveals a bug in the conversion arithmetic, which is far easier to catch this way than by trusting a single one-directional conversion against evidence where the correct answer is not already known.

Key takeaway: Key takeaway

Every timestamp has to be converted to one common reference before it can be trusted next to any other. Chrome's microseconds-since-1601 is this unit's concrete example of why; once every source speaks the same clock, building a timeline is nothing more than collecting events into a list and sorting it.

Assessments

Unit Assessment

Digital Forensics with Python

20 questions30 minPass: 60%

Start exam →

Comprehensive Assessment

Python for Cyber Security: Complete Assessment

100 questions120 minPass: 60%

Start final exam →

Related to this topic

Continue learning

Reference material

Cheatsheet

Python for Cyber Security — Cheatsheet

v1.0

Open resource

MCQ Bank

Python for Cyber Security — MCQ Bank

v1.0

Open resource

Question Bank

Python for Cyber Security — Question Bank

v1.0

Open resource

eBook

Python for Cyber Security — eBook

v1.0

Open resource

Discussion

Loading comments…
More articlesTest your knowledge
EZ MentorAI · Free

Converting Timestamps and Building a Timeline

Hi! I'm EZ Mentor

Your AI tutor for
Converting Timestamps and Building a Timeline

Sign in to ask, it's free.

EZ Mentor is AI-powered · Answers may not be perfect · 10 free questions / day

EZ LearnEZ Learn

Structured learning across Reverse Engineering, Cloud Security, and Research Methodology, plus games and practice tools in EZ Arena. Free, and open to anyone.

EZ Learn

  • Courses
  • EZ Articles
  • EZ Watch
  • EZ Talks
  • EZ Bytes
  • Cyber Hygiene

EZ Library

  • All Resources
  • eBooks & PDFs
  • Question Banks
  • MCQ Banks
  • Cheatsheets

EZ Exams

  • All Exams
  • REMA
  • Cloud Security
  • Research Methodology
  • Python for Cyber Security
  • Cyber Law & IPR
  • Community
  • EZ Board

EZ Arena

  • EZ Games
  • Live Quiz
  • ML Challenges
  • दिशा - Hygiene
  • सजग - Awareness
  • अभ्यास - Practice

Platform

  • About
  • Contact
  • Terms of Use
  • Disclaimer
  • Verify Certificate
  • Events

© 2026 EZ Learn by EpochZero. Educational content for learning purposes.

Platform Lead: Ashish Revar