Working With Time Zones in an AWS Lambda Python Function

Working With Time Zones in an AWS Lambda Python Function

Get the gist on how to work with time zones using environment variables and built-in modules in an AWS Lambda function written in Python.

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, 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 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. 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

💡
In Terraform, you can set environment variables using the environment configuration block in the aws_lambda_function resource.

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 (for example, one that is returned by the datetime.now() function), you should use the datetime.stimezone() function similar to the example below:

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 as an argument, which you can construct with the IANA time zone identifier.

As a warning, do NOT use the datetime.replace() function 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 for other useful information :)