How to Filter Google Timeline Data by Year in the Google Timeline Visualizer

To filter Google Timeline data by year, generate sortable date keys using the pointDateKey helper in timeline.ts, then use String.prototype.startsWith to isolate points matching your target year.

The google-timeline-visualizer converts raw Google Takeout exports into structured journeys. When analyzing multi-year location history, isolating specific years requires working with the library's timestamp normalization utilities. This guide demonstrates how to filter Google Timeline data by year using the repository's core data-processing functions.

Understanding the Timeline Data Structure

Every location entry in the visualizer is stored as a GeoPoint object containing a timestamp (instant) and an optional original recording date (recordedDate). The library normalizes these timestamps through helper functions defined in web/src/timeline.ts.

The pointDateKey function converts any GeoPoint into a consistent YYYY-MM-DD string format:

// Located in web/src/timeline.ts#L97-L99
function pointDateKey(point: GeoPoint): string {
  return point.recordedDate ?? formatDateKey(point.instant);
}

This normalization enables reliable string-based filtering. The function falls back to formatting the instant timestamp when recordedDate is unavailable, ensuring every point has a comparable date representation.

Building a Year Selector

Step 1: Extract Available Years

Before filtering, derive the list of unique years present in your dataset. The availableYears function slices the first four characters from each date key to isolate the year component:

function availableYears(points: GeoPoint[], locale: string): string[] {
  const keys = new Set(points.map(p => pointDateKey(p).slice(0, 4))); // Extract "YYYY"
  return Array.from(keys).sort(); // Returns ["2019", "2020", "2021", ...]
}

This produces a sorted array of distinct years suitable for populating UI dropdowns or command-line selectors.

Step 2: Filter Points by Specific Year

The filterByYear function leverages the startsWith method to retain only points from your target year:

function filterByYear(points: GeoPoint[], year: string): GeoPoint[] {
  return points.filter(p => pointDateKey(p).startsWith(year));
}

Pass a four-digit year string (e.g., "2022") to receive a filtered GeoPoint[] array ready for rendering or export.

Filtering Across Year Ranges

For multi-year analysis, reuse the existing selectRange utility found at web/src/timeline.ts#L20-L25. This function operates on month keys (YYYY-MM), allowing you to construct year-based ranges by anchoring to January and December:

function filterByYearRange(
  points: GeoPoint[],
  startYear: string,
  endYear: string,
): GeoPoint[] {
  const start = `${startYear}-01`;  // January of start year
  const end   = `${endYear}-12`;      // December of end year
  return selectRange(points, start, end);
}

This approach maintains compatibility with the library's existing range-selection logic while achieving year-level granularity.

Complete Implementation Workflow

Integrate the filtering functions into your data pipeline as follows:

import {
  parseTimelineJson,
  availableYears,
  filterByYear,
} from './timeline';

// 1. Load and parse the Google Takeout JSON
const rawData = await fetch('timeline.json').then(r => r.json());
const points = parseTimelineJson(rawData);   // web/src/timeline.ts#L85-L87

// 2. Build your year selector
const years = availableYears(points, 'en-US');
populateYearDropdown(years);  // Your UI implementation

// 3. Filter for a specific year
const chosenYear = '2021';
const yearPoints = filterByYear(points, chosenYear);

// 4. Render the filtered journey
drawJourney(yearPoints);

The parseTimelineJson function (lines 85-87) handles legacy format detection, deduplication, and normalization before the year filtering logic executes. For best results, apply outlier filtering from web/src/outlier.ts before the year selection step to remove GPS anomalies that might skew your dataset.

Summary

  • GeoPoint objects store location data with normalized timestamps in web/src/timeline.ts.
  • Use pointDateKey to generate YYYY-MM-DD strings for consistent date comparisons.
  • Build year selectors with availableYears, which extracts unique years by slicing the first four characters of date keys.
  • Filter specific years using filterByYear with the startsWith string method.
  • Handle year ranges by constructing month-based start/end strings and passing them to selectRange (lines 20-25).
  • Always parse raw JSON through parseTimelineJson to ensure data normalization before filtering.

Frequently Asked Questions

What date format does the visualizer use internally?

The visualizer normalizes all timestamps to YYYY-MM-DD strings through the pointDateKey function. This format ensures lexicographical sorting matches chronological order, making year extraction as simple as reading the first four characters.

Can I filter by multiple non-consecutive years?

Yes. Simply call filterByYear for each target year and merge the results, or modify the filter predicate to check against an array of year strings using ['2020', '2022'].some(year => dateKey.startsWith(year)).

Where is the core filtering logic implemented?

All date-key generation and range selection utilities reside in web/src/timeline.ts. The pointDateKey function is defined at lines 97-99, while selectRange appears at lines 20-25. Application-level integration examples are visible in web/src/main.ts.

Should I remove GPS outliers before filtering by year?

Yes. Apply outlier detection from web/src/outlier.ts before year filtering. Spurious GPS points often carry incorrect timestamps that could appear in incorrect years if not filtered first, contaminating your yearly datasets.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →