Date and Timezone oddities on Node, Browser and Lambda
Tags: javascript, debugging, node, aws
Published: 2019-04-01 09:42:07

---
title: Date and Timezone oddities on Node, Browser and Lambda
published: true
cover_image: https://thepracticaldev.s3.amazonaws.com/i/rtahs9snz6pi1ecb7br1.jpg
description: TZ and Date differences on node and browser
tags: #javascript, #debugging, #nodejs, #aws
---

If I run 

```
node
> new Date()
```
in the terminal, I get this timestamp: **2019-03-28T13:37:22.081Z**
while if I run `new Date()` in the browser console I will get 
I get this timestamp: **Thu Mar 28 2019 14:37:39 GMT+0100 (Central European Standard Time)**  which is more accurate, since I am in Hamburg, which is 1h+.

If I bring back the clock of my pc 5 hours and run the same code I get **2019-03-28T08:43:26.895Z** from node and **Thu Mar 28 2019 09:43:14 GMT+0100 (Central European Standard Time)** from the browser console. 

![back to the future](https://media.giphy.com/media/7TZvWKVkm0xXi/giphy.gif)

This makes perfect sense - nothing special here. (even though I was slightly surprised by the different outputs on the Date constructor in the browser and in nodeJs).

What will the Timezone be when I run my code on Lambda? Will it be different if the code runs **on containers in different regions**?
Of course - luckily - not! 
> No matter where the lambda is running it will always have the UTC timezone.

This can be tested by running `console.log(process.env.TZ)`. TZ is a [Lambda reserved env variable](https://docs.aws.amazon.com/en_us/lambda/latest/dg/current-supported-versions.html) which will print **:UTC**.   

Therefore ( unless I messed around with my pc clock) new Date() on my deployed Lambda will give me the same time as when it runs locally.

Even here nothing really surprising.
![boring..](https://media.giphy.com/media/IZKuUgbb8g0Yo/giphy.gif)

What screwed my code this morning was **Date.toLocaleDateString()**

Since we had to pass to a RestAPI a query param with a date in the format _YYYY-MM-DD_ we were using `d.toLocaleDateString('de-DE')` and then manipulating the output to format it as expected. It was a silly method but we didn't want to be bothered importing [Moment.js](https://www.npmjs.com/package/moment) for this tiny thing.

Everything was working fine, I had many unit tests proving different dates and formats. Then after deploying ( on a Development Stage, of course ): BAM!,  nothing works... API was rejecting my request.

Then i realized that the format was broken because on AWS the toLocaleDateString behaves differently.  Well, it is not just AWS, it is Node that behaves differently from the Browser, and how the toLocaleDateString works on Node depends on the Node version and the **icu** built with it. 

On my machine 
```
    const d = new Date()
    console.log(d)
    console.log("toLocaleDateString('')",d.toLocaleDateString())
    console.log("d.toLocaleDateString('en-US')",d.toLocaleDateString('en-US'))
    console.log("d.toLocaleDateString('de-DE')",d.toLocaleDateString('de-DE'))
```
was printing : 
```
2019-03-28T09:04:31.507Z
toLocaleDateString('') 3/28/2019
d.toLocaleDateString('en-GB') 28/03/2019
d.toLocaleDateString('en-US') 3/28/2019
d.toLocaleDateString('de-DE') 28.3.2019
```
while on the lambda 
```
2019-03-28T14:05:14.952Z
toLocaleDateString('') 2019-3-28
d.toLocaleDateString('en-GB') 3/28/2019
d.toLocaleDateString('en-US') 3/28/2019
d.toLocaleDateString('de-DE') 2019-3-28
```
Unfortunately I did not have the time to further investigate how the [intl module](https://nodejs.org/api/intl.html#intl_internationalization_support) of node works based on the Build, nor how to use the [full-icu package](https://www.npmjs.com/package/full-icu) as mentioned in [this issue]https://github.com/nodejs/node/issues/8500), so in the end we dropped the reverseFormat method and we simply grabbed each value individually to construct the string we wanted: 
`d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate())`.

Not nice, but sometimes you also have to accept the fact and meet with your deadlines ( and the reverse method was not that smart anyway..)

To recap:

- No matter which region your Lambda runs on - timezone will always be UTC. 
- Due to the ICU build in the node version running toLocaleDateString might have unexpected output. 
- If you want to get the current time on a specific timezone then you have to use [moment-timezone](https://www.npmjs.com/package/moment-timezone)   ( overwriting process.env.TZ does not have any effect on the timezone used by Date)
 
Hope it helps.