All posts
Investigation · Extended Events

Extended Events Timezones

Do Extended Events timestamps in SSMS show local or server time? I test it with a SQL Server container in another timezone and check the underlying UTC data.

Tom · 3 min read
Extended Events Timezones

Foreword

I've helped answer another question that appeared on the SQL Server Slack:

Are timestamps in XE event files you view in SSMS local or server time?

To test this, I need a server in a different timezone than the client (SSMS). The quickest and easiest tool for that is containers, more specifically Docker. I've written before about why I reach for containers.

Don't have Docker installed? Grab it from this guide. You can still follow along with the examples even without it.

Preparing the environment

To create a new SQL Instance, we will just run the following command.
If you don't have the latest SQL Server 2019 image, it will download it for you (roughly 1.5 GB).

docker run `
-e 'ACCEPT_EULA=Y' `
-e 'SA_PASSWORD=Password5' `
-e 'MSSQL_PID=Developer' `
-e TZ='America/Los_Angeles' `
-p 14338:1433 `
-d `
--name xeinstance `
mcr.microsoft.com/mssql/server:2019-latest

Command explanation

docker run The command to create and run the container
-e Environment variables. The EULA and SA Password are required; TZ sets the timezone needed for our test
-p port mapping in format host:container. I'm using a different port on the host in case you already have a local instance. If you are based in the LA timezone, you can pick a different one, for example, Asia/Singapore.
-d Detached
--name Name of the container for easy reference
mcr.microsoft.com/mssql/server:2019-latest Image name:tag. In our case, the latest CU of SQL Server 2019

If you need more information, you can run docker run --help or visit the Documentation. If the container is created successfully, its ID will appear. You can also check with the docker ps -a command.

Additional Docker references

No need for this now, but if you want to dig deeper into Docker, here are some useful links:

Test in the SSMS

  • Connect to localhost,14338 (or .,14338 if you don't like typing).
  • Select SQL Server Authentication
    • Login = sa
    • Password = Password5

Connection popup in SSMS

Open a new query window and run this to confirm the server time.

SELECT
   SYSDATETIMEOFFSET()
   , GETUTCDATE()

The timezone will match our config from earlier.

We don't need to create a new XE session as the system_health will be running by default. If you're new to capturing errors this way, see Investigating errors with Extended Events.

To open it, navigate to the Docker instance in Object Explorer.
Go to Management\Extended Events\Sessions\System_health and double-click the package0.event_file.

We can add an additional column to the default view as per the image instructions. SSMS event file viewer with side-by-side timestamp and timestamp (UTC) columns; the local column reads one hour ahead, showing SSMS converts the stored UTC value to client local time

I am in the GMT+1 timezone, so we can see that the event file view shows time local to the SSMS client.

Digging deeper

Let's look at the underlying data with the fn_xe_file_target_read_file DMF.

SELECT TOP (10)
   ca.eventDataXml.value('event[1]/@timestamp', 'datetime2(3)') AS tmpstmp
   , ca.eventDataXml
FROM sys.fn_xe_file_target_read_file('system_health*.xel', NULL, NULL, NULL) AS ef
CROSS APPLY
(
   VALUES (CAST(ef.event_data AS xml))
) ca(eventDataXml)
ORDER BY ef.timestamp_utc DESC

This gives us a sample of the events. There is only one underlying timestamp column, and it is stored in UTC. SSMS converts it to your local time on the fly.

So, back to the original question: the Extended Events file viewer shows time local to the SSMS client, not the server. The data on disk is always UTC.

Thank you for reading

Tom
Tom, TSQL Dev

SQL Server consultant from Czechia.

Give me a problem where the answer isn't obvious and the evidence doesn't add up. That's my idea of a good time.