---
title: "Time Zones"
description: "LEAN is an international trading engine, so it can operate across time zones. The exchange, your algorithm, and the data can all have different time zones."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/time-zones
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/time-zones.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/01%20Key%20Concepts/05%20Time%20Modeling/03%20Time%20Zones
modified: 2026-10-30
index: https://www.quantconnect.com/llms.txt
---

# Time Zones

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Key Concepts > Time Modeling > Time Zones

> Code examples are shown in Python. Append `?lang=csharp` to this URL for the C# version of this page.

## Introduction

LEAN is an international trading engine, so it can operate across time zones. The exchange, your algorithm, and the data in your algorithm can all have different time zones.

## Exchange Time Zone

Exchanges are located in different areas, so they can have different time zones. LEAN tracks the time zone of each exchange so that you receive the correct data at the right point in time in your algorithm. If you have multiple exchanges in your algorithm from different time zones, LEAN synchronizes them to your algorithm time. Furthermore, if you set up [time period consolidators](https://www.quantconnect.com/docs/v2/writing-algorithms/consolidating-data/consolidator-types/time-period-consolidators.md), LEAN consolidates the data based on the data time zone.

To get the time zone of the exchange that a `Security` trades on, use its `exchange.hours.time_zone` property.

```python
# Get the time zone of the exchange for a specific asset.
time_zone = self.securities[self._symbol].exchange.hours.time_zone
```

## Algorithm Time Zone

LEAN supports international trading across multiple time zones and markets, so it needs a reference time zone for the algorithm to set the `time`. The default time zone is Eastern Time (ET), which is UTC-4 in summer and UTC-5 in winter. To set a different time zone, call the `set_time_zone` method. This method accepts either a string following the [IANA Time Zone database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) convention or a [NodaTime](https://nodatime.org/).DateTimeZone object. If you pass a string, the method converts it to a `NodaTime.DateTimeZone` object. The `TimeZones` class provides the following helper attributes to create `NodaTime.DateTimeZone` objects:

*Members of `QuantConnect.TimeZones` (JSON): https://www.quantconnect.com/services/inspector?type=T:QuantConnect.TimeZones&language=python*

```python
self.set_time_zone("Europe/London")
self.set_time_zone(TimeZones.CHICAGO)
```

To get the time zone of your algorithm, use the `time_zone` property.

```python
# The algorithm timezone property can assist with multi-asset trading.
time_zone = self.time_zone
```

To get the algorithm time in Coordinated Universal Time (UTC), use the `utc_time` property.

```python
# Access the current UTC time to coordinate multi-timezone events or improve logging.
utc_time = self.utc_time
```

The `time` property is a naive `datetime` object in the algorithm time zone. The `time` and `end_time` properties of data objects are also naive and use the exchange time zone. The `utc_time` property of the algorithm and of [order events](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/order-events.md) is a timezone-aware `datetime` object in UTC.

If you subtract a naive `datetime` from a timezone-aware one, Python raises a `TypeError`. To compare two times, use values of the same kind. Save `self.utc_time` when you later subtract it from the `utc_time` of an order event. Save `self.time` when you later compare it with `self.time` or the times of data objects.

```python
def on_data(self, slice: Slice) -> None:
    if not self.portfolio.invested:
        # Save the UTC time before you place the order because backtests can fill it immediately.
        self._order_utc_time = self.utc_time
        self.market_order(self._symbol, 1)

def on_order_event(self, order_event: OrderEvent) -> None:
    if order_event.status == OrderStatus.FILLED:
        # Both values are timezone-aware, so the subtraction succeeds.
        time_to_fill = order_event.utc_time - self._order_utc_time
```

## Data Time Zone

Datasets can have different time zones because the time zone is up to the data provider, where they are located, and where they collect the data. LEAN converts their time zones to their [exchange time zone](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/time-zones.md#03-Exchange-Time-Zone) and synchronizes them to your algorithm time.

To get the time zone of a dataset, view the listing page in the [Dataset Market](https://www.quantconnect.com/datasets) or call the `GetDataTimeZone` method.

```python
# Get the time zone of an asset.
time_zone = self.market_hours_database.get_data_time_zone(Market.USA, self._symbol, SecurityType.EQUITY)
```

## Examples

The following examples demonstrate some common practices for time zone modeling.

### Example 1: Futures Time Zone

The following algorithm changes its time zone to be the same as the EMini SP500 Futures exchange, i.e., Chicago time zone. It is comparable in validating data across different sources and has a more convenient time notification without further conversion.

```python
class TimeZoneModelingAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)

        # Request ES future data for trading.
        self._future = self.add_future("ES", Resolution.MINUTE,
            extended_market_hours=True,
            data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
            data_mapping_mode=DataMappingMode.OPEN_INTEREST,
            contract_depth_offset=0)

        # Set the time zone to be the same as the Future (Chicago).
        # It will make the time in the backtest more comparable and easily analyzed with any other data sources.
        # Performance of the backtest will only be altered by this change if the trading logic depends on the Time property.
        self.set_time_zone(self._future.exchange.time_zone)

        self.ticket = None

    def on_data(self, slice: Slice) -> None:
        if not self.portfolio.invested and not self.ticket:
            contract = self.securities[self._future.mapped]
            # Set a limit price that repsects the brokerage's precision requirements.
            limit_price = self._adjust_limit_price(contract, contract.price * 0.995)
            self.ticket = self.limit_order(contract.symbol, 1, limit_price)

        # Cancel unfilled orders if they are not filled within 2 minutes to avoid stale fills.
        # Note that the Time property in the order ticket is in UTC timezone.
        if self.ticket.status != OrderStatus.FILLED and self.ticket.time + timedelta(minutes=2) < self.utc_time:
            # You can change to a different time zone and compare the log differences.
            self.ticket.cancel(f"{self.time} :: utc: {self.utc_time} :: Order canceled due to placed over 2 minutes")

            self.ticket = None

    def _adjust_limit_price(self, security, price, round_up=True):
        pip = security.price_variation_model.get_minimum_price_variation(
            GetMinimumPriceVariationParameters(security, price)
        )
        return (int(price / pip) + int(round_up)) * pip
```
