# Working With Time Zones in an AWS Lambda Python Function

## Introduction

Lately I have been working on automation solutions for sending summary reports of CloudWatch metrics. After figuring out [how to best deploy an AWS Lambda layer](https://blog.avangards.io/3-ways-to-publish-and-use-an-aws-lambda-layer-in-terraform), development was smooth sailing until I encountered an issue related to time zones. While the report, which contains hourly statistics for the past 24 hours, had the correct information when run on my laptop, the displayed hours were off by a few hours when tested as a Lambda function deployed in AWS. It was fortunately not difficult to resolve with some reading, but I figured that I could share a couple quick tips in this blog post to save a fellow engineer a few minutes.

## Tip 1: Set the TZ environment variable for the Lambda function

As per the [Using Lambda environment variables](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime) topic in the AWS Lambda Developer Guide, you can control the Lambda runtime time zone by setting the unreserved environment variable `TZ`. By default, the `TZ` environment variable is set to `UTC`, however you can set it to a standardized [Internet Assigned Numbers Authority (IANA) time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). For example, my customer resides in the East coast, so I set `TZ` to `America/New_York`:

![Setting the TZ environment variable in the AWS Management Console](https://cdn.hashnode.com/res/hashnode/image/upload/v1709365247580/47b3efa8-a6a2-4033-bd9c-c74d12c10c4b.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">In Terraform, you can set environment variables using the <a target="_blank" rel="noopener noreferrer nofollow" href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function#environment" style="pointer-events: none"><code>environment</code> configuration block</a> in the <code>aws_lambda_function</code> resource.</div>
</div>

After this, the Lambda function generates the report with the hours matching the customer's time zone. This is the simplest way of changing the time zone without code.

## Tip 2: Use the datetime and zoneinfo modules properly

If you need to change the time zone of a [`datetime` object](https://docs.python.org/3/library/datetime.html#datetime-objects) (for example, one that is returned by the [`datetime.now()` function](https://docs.python.org/3/library/datetime.html#datetime.datetime.now)), you should use the [`datetime.stimezone()` function](https://docs.python.org/3/library/datetime.html#datetime.datetime.astimezone) similar to the example below:

```python
from datetime import datetime
from zoneinfo import ZoneInfo
import os

# Provide the IANA time zone as an env var
display_time_zone = os.environ.get("DISPLAY_TIME_ZONE")
# Time zone = The value of the TZ env var (UTC if not set)
current_dt = datetime.now() 
# Time zone = the time zone provided via the DISPLAY_TIME_ZONE env var
current_dt = current_dt.astimezone(ZoneInfo(display_time_zone))
```

The `datetime.astimezone()` function takes a [`ZoneInfo` object](https://docs.python.org/3/library/zoneinfo.html#the-zoneinfo-class) as an argument, which you can construct with the IANA time zone identifier.

As a warning, do NOT use the [`datetime.replace()` function](https://docs.python.org/3/library/datetime.html#datetime.datetime.replace) to set the `tzinfo` attribute for this scenario, since it will only attach a time zone to the `datetime` object and not adjust the actual hours according to the time zone offset. So what you expect to be "now" displayed in the specified time zone would actually be off by the difference between the original and new time zone offsets, resulting in a skewed time frame.

## Summary

With these two tips, you can effectively set the time zone of `datetime` objects in your Lambda function in Python. I hope you find this short blog post helpful and would encourage you to keep checking [my blog](https://blog.avangards.io/) for other useful information :)
