Learn / Programming / Python / JSON, Dates and the Standard Library

Python · Lesson 14 of 15

JSON, Dates and the Standard Library

Read and write JSON, work with dates and durations, and reach for collections and pathlib.

  • Intermediate
  • 14 min read
  • 3 objectives

Before this lessonLesson 13: Modules, Packages and pip

What you will learn

  • Convert data to and from JSON
  • Do date arithmetic
  • Count and group with collections

Two things show up in almost every real project: exchanging data with other systems, and dealing with time. JSON is the near-universal data format of web APIs, and the datetime module handles dates without you counting days by hand. Both come with Python, so there is nothing to install.

What JSON looks like

JSON is text that describes data using objects (like Python dicts), arrays (lists), strings, numbers, booleans and null (Python's None). The json module converts between that text and Python objects. dumps turns a Python object into a JSON string; loads parses a JSON string back.

import json

user = {"id": 1, "name": "Ada", "admin": True, "tags": ["math", "code"], "manager": None}

text = json.dumps(user)
print(text)

back = json.loads(text)
print(back["tags"][0], back["manager"])
Output
{"id": 1, "name": "Ada", "admin": true, "tags": ["math", "code"], "manager": null}
math None

Pretty printing and reading and writing files

Pass indent to make the output readable and sort_keys for a stable order. The file versions are json.dump and json.load (no trailing s), which take an open file.

import json

config = {"debug": False, "port": 8000, "hosts": ["a.example", "b.example"]}
print(json.dumps(config, indent=2, sort_keys=True))
Output
{
  "debug": false,
  "hosts": [
    "a.example",
    "b.example"
  ],
  "port": 8000
}
import json

with open("config.json", "w") as f:
    json.dump(config, f, indent=2)

with open("config.json") as f:
    loaded = json.load(f)
print(loaded["port"])

Dates and times

date holds a day, datetime a day and a time, and timedelta a length of time. Subtracting two dates gives a timedelta, and adding one to a date moves it forward.

from datetime import date, datetime, timedelta

launch = date(2026, 3, 1)
today = date(2026, 1, 15)

print(launch - today)
print((launch - today).days)
print(today + timedelta(days=30))
print(today.weekday(), today.strftime("%A, %d %B %Y"))

meeting = datetime(2026, 1, 15, 9, 30)
print(meeting + timedelta(hours=2, minutes=15))
Output
45 days, 0:00:00
45
2026-02-14
3 Thursday, 15 January 2026
2026-01-15 11:45:00

Parsing and formatting

strftime formats a date as text using codes like %Y (year), %m (month) and %d (day). strptime does the reverse. For the standard ISO format use isoformat() and fromisoformat(), which is the safest thing to store or send.

from datetime import datetime

parsed = datetime.strptime("15/01/2026 18:45", "%d/%m/%Y %H:%M")
print(parsed)
print(parsed.isoformat())
print(parsed.strftime("%b %d, %Y at %I:%M %p"))
print(datetime.fromisoformat("2026-01-15T18:45:00").year)
Output
2026-01-15 18:45:00
2026-01-15T18:45:00
Jan 15, 2026 at 06:45 PM
2026

More standard-library helpers

collections.Counter counts things, defaultdict removes the "does this key exist yet?" check when grouping, and pathlib.Path is the modern way to build file paths without string gluing.

from collections import Counter, defaultdict
from pathlib import Path

votes = ["red", "blue", "red", "green", "red", "blue"]
print(Counter(votes).most_common())

by_length = defaultdict(list)
for word in ["kiwi", "fig", "plum", "pear", "lime"]:
    by_length[len(word)].append(word)
print(dict(by_length))

p = Path("data") / "reports" / "2026.csv"
print(p.name, p.suffix, p.parent)
Output
[('red', 3), ('blue', 2), ('green', 1)]
{4: ['kiwi', 'plum', 'pear', 'lime'], 3: ['fig']}
2026.csv .csv data/reports

Common mistakes

  • Mixing up dump/load (files) with dumps/loads (strings).
  • Forgetting that JSON object keys are always strings, so {1: "a"} comes back as {"1": "a"}.
  • Comparing naive and time-zone-aware datetimes, which raises TypeError.
  • Formatting dates by hand with string slicing instead of strftime.
# Write your solution here
Up next · Lesson 15Testing and DebuggingWrite tests with pytest, read tracebacks, and track down bugs with print and the debugger.