How TeslaMate Handles Timezone Data with TZData for Location Records

TeslaMate leverages the tzdata library alongside Timex to manage IANA timezone databases, enabling conversion of naive timestamps from imported location data to specific timezones and displaying all temporal data in the user's local time.

The teslamate-org/teslamate repository relies on robust timezone handling with TZData for location data to ensure timestamps across drives and charging sessions display correctly for users worldwide. By combining the tzdata package with the Timex datetime library, the application maintains a complete timezone database that powers everything from CSV imports to the Phoenix LiveView web interface.

Configuration and Dependencies

Declaring Dependencies in mix.exs

The foundation begins in the project configuration where TZData is declared as a dependency. The mix.exs file includes {:tzdata, "~> 1.1"} alongside {:timex, "~> 0.26"}, ensuring both the underlying zoneinfo database and the Elixir API are available at compile time.

Runtime Configuration with TZDATA_DIR

In config/runtime.exs, the application configures the data directory for zoneinfo files using the TZDATA_DIR environment variable. The configuration line config :tzdata, :data_dir, System.get_env("TZDATA_DIR", "/tmp") sets the storage path, defaulting to /tmp when the variable is not present. This directory holds the IANA timezone database that tzdata loads when the application boots.

User Timezone Selection

Populating the Timezone Dropdown

The LiveView interface at lib/teslamate_web/live/import_live/index.ex retrieves the complete list of available zones by calling Timex.timezones/0. This function queries the :tzdata application for all canonical identifiers (such as "Europe/Berlin" or "America/New_York") and presents them in the user interface for selection.

Persisting User Preferences

Once a user selects their preferred zone, the application stores the choice in the LiveView state within a %Settings{timezone: tz} struct. The changeset/1 and assign/3 logic in the same file validates and persists this selection, making it available for downstream processing of location records.

Applying Timezones to Location Data

Processing Imported CSV Files

When importing historical data via lib/teslamate/import.ex, the run/1 and create_event_streams/2 functions receive the chosen timezone parameter and pass it downstream. This ensures that all timestamps extracted from CSV files undergo consistent timezone conversion before storage.

Converting Naive Datetimes

Raw timestamps from imported files typically arrive as naive datetimes without zone information. The application uses Timex.parse!/2 to parse the raw strings, then pipes the result through Timex.to_datetime/2 to attach the selected zone. For example:


# Parse the naive timestamp from CSV

naive = Timex.parse!("2024-04-01T12:34:56", "{ISO:Extended}")

# Convert to zoned datetime using user's selected timezone

zoned = Timex.to_datetime(naive, "Europe/Berlin")

# Result: %DateTime{...} with timezone %Timex.Timezone{...}

The resulting DateTime struct is then stored in the position record within TeslaMate.Log.Position.

Rendering Localized Timestamps

When displaying drives or charging sessions, various LiveViews (including car_live and drive_live modules) format timestamps using Timex.format!/2. The function call Timex.format!(datetime, "{ISO:Extended Z}") renders the stored UTC instant in the user's local timezone, ensuring the web interface shows dates relative to the location where the event occurred.

Summary

  • mix.exs declares the {:tzdata, "~> 1.1"} dependency alongside Timex.
  • config/runtime.exs sets the data directory via the TZDATA_DIR environment variable, defaulting to /tmp.
  • lib/teslamate_web/live/import_live/index.ex retrieves available zones using Timex.timezones/0 and persists user selection.
  • lib/teslamate/import.ex applies the selected timezone to naive timestamps during CSV import using Timex.to_datetime/2.
  • Display functions across LiveViews use Timex.format!/2 to render timestamps in the user's local zone.

Frequently Asked Questions

Where does TeslaMate store the IANA timezone database files?

The database is stored in the directory specified by the TZDATA_DIR environment variable, as configured in config/runtime.exs. If this variable is not set, the system defaults to /tmp, which tzdata uses to cache the zoneinfo files after the initial download.

How does TeslaMate handle timestamps without timezone information during import?

The lib/teslamate/import.ex module receives the user-selected timezone from the settings state and applies it using Timex.to_datetime/2. This converts naive timestamps parsed from CSV files into proper DateTime structs with the correct UTC offset before they are persisted to the database.

What Elixir functions does TeslaMate use to list available timezones?

The application calls Timex.timezones/0 in lib/teslamate_web/live/import_live/index.ex, which internally queries the :tzdata application for the complete list of IANA timezone identifiers available in the runtime database.

Can the timezone data directory be customized for containerized deployments?

Yes. Administrators can set the TZDATA_DIR environment variable to a persistent volume path (such as /var/lib/teslamate/tzdata) before starting the application, ensuring the IANA database survives container restarts and avoiding reliance on the temporary /tmp directory.

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 →