41

Is there a way to obtain the local timezone from the system (eg:- ubuntu) using nodejs?

I used moment.js to extract the date and time values. But couldn't find a way to extract the timezone as well.

Malith
  • 685
  • 1
  • 8
  • 14
  • 8
    try this `new Date().getTimezoneOffset()`. – vkstack Aug 12 '16 at 10:23
  • Thanks. It worked. But I needed it formatted in "hh:mm"; so I used moment.js with `console.log(''.concat(offset < 0 ? "-" : "+",moment(''.concat(Math.abs(offset/60),Math.abs(offset%60) < 10 ? "0" : "",Math.abs(offset%60)),"hmm").format("HH:mm"));` – Malith Aug 12 '16 at 11:48
  • Duplicate of [Getting the client's timezone offset in JavaScript](https://stackoverflow.com/questions/1091372/getting-the-clients-timezone-offset-in-javascript) – Dan Dascalescu Apr 27 '19 at 21:35

4 Answers4

56

The existing answers will tell you the current timezone offset, but you will have issues if you are comparing historic/future points in time as this will not cater for daylight saving changes.

In many timezones, the offset varies throughout the year and these changes occur at different dates or not at all depending on the latitude. If you only have UTC time and an offset, you can never be sure what the offset will be in that location at various other times during the year.

For example, a UTC+2:00 offset could refer to Barcelona in the summer or Ivory Coast all year round. The 2hr offset will always display the correct time in Ivory Coast but will be 1hr out for half the year in Barcelona.

Check out this great article covering the above.

How do we cater for all these time zone issues? Well, it's pretty simple:

  1. Save all times in UTC
  2. Store the time zone string for where this event occurred

In modern browsers or node.js, you can get the local IANA time zone string like this:

Intl.DateTimeFormat().resolvedOptions().timeZone // eg. 'America/Chicago'

You can then use this timezone string in a library like Luxon to help offset your captured UTC times.

DateTime.fromISO("2017-05-15T09:10:23", { zone: "Europe/Paris" });
Tim
  • 7,746
  • 3
  • 49
  • 83
  • 2
    This is the correct answer. Offsets and timezones are related but different, and can cause havoc if your code requires daylight savings to be taken into account as mentioned. – Brideau Aug 23 '17 at 13:31
  • Could you please let me know if the following is correct? If the UI (for a user in Chicago) sends a date to the server (based in London) it would send the date in ISO8601/RFC3339 format (2018-06-23T11:00:00Z) and the timezone from the browser ('America/Chicago').The server would send those 2 fields to the UI when needed, the UI could transform them into the browser's system timezone. If the date is generated on the server-side instead, it would send to the UI the date + the name of the timezone set on the server ('London'), then the UI could format this to change it to Chicago timezone. – MartaGalve Jul 31 '18 at 04:43
  • Regarding historic dates, I don't see why the timezone name is needed. If you save the offset when the date is generated (for ex, +2:00 in Barcelona in summer), when you are in winter in Barcelona +1:00 you will get from the server a date with +2:00, which will be correct. I only see the need for time timezone name for future dates. Am I misunderstanding this? – MartaGalve Jul 31 '18 at 05:13
  • As you say, if UTC is stored on the server, from anywhere in the world you will be able to see what date/time this refers to in the timezone you are currently residing. If you want to know what date/time this refers to in the location where it was recorded, you will need the zone name to accurately resolve this. If timestamps are always recorded and viewed from the same zone you don't need this information but that is a big assumption. – Tim Jul 31 '18 at 10:05
  • 3
    [The Intl API is standard nowadays](https://stackoverflow.com/questions/1091372/getting-the-clients-timezone-offset-in-javascript/55204472#55204472), which makes moment.js no longer necessary for this simple task. Also, there are far lighter alternatives to moment.js now. – Dan Dascalescu Apr 27 '19 at 21:38
  • 3
    Since the question is about Node.js, it's worth noting that Intl has been available since version 0.11. – cleong Dec 17 '19 at 17:15
  • `node -p 'Intl.DateTimeFormat().resolvedOptions().timeZone'` -> `Europe/Paris`; `TZ=UTC node -p 'Intl.DateTimeFormat().resolvedOptions().timeZone'` -> `UTC` – jakub.g Dec 22 '21 at 12:08
  • Alternatively when formatting time, you can use `timeStyle:"long"`, this `node -p "Intl.DateTimeFormat('fr-FR', { timeStyle: 'long' })` will print `UTC` or `UTC+X` – jakub.g Dec 22 '21 at 12:14
13

It is very simple.

var x = new Date();
var offset= -x.getTimezoneOffset();
console.log((offset>=0?"+":"")+parseInt(offset/60)+":"+String(offset%60).padStart(2, "0"))

And there is nothing else or you can see if momentJS can help you or not.

Note: This answer is outdated, you can suggest to add in it.

vkstack
  • 1,582
  • 11
  • 24
  • 2
    this one is nice but if offset is negative you will get -- 4:0, it's also a good idea to add a padding function – Jesus Gomez Sep 18 '17 at 21:18
  • 2
    Offset is not the same as timezone. Two timezones can have the same offset but have different DST rules. – Justin Johnson Feb 27 '19 at 20:53
  • [moment.js is no longer recommended.](https://stackoverflow.com/questions/1091372/getting-the-clients-timezone-offset-in-javascript/55204472#comment97145204_40435316) – Dan Dascalescu Apr 27 '19 at 21:34
  • To avoid the `--` bug that Jesus Gomez mentions above, and to include padding on the minutes, the final line should be: `console.log((offset>=0?"+":"")+parseInt(offset/60)+":"+String(offset%60).padStart(2, "0"))` – Peter Rust Jan 09 '23 at 23:01
4

It is this easy, no libraries needed:

console.log("test ...")
let d = new Date()
console.log("UTC time " + d)
let ank = d.toLocaleString('en-US', { timeZone: 'America/Anchorage' });
console.log("your time zone " + ank)

enter image description here

How to see the exact time zone names on most servers:

ls /usr/share/zoneinfo

Works flawlessly:

You'll get the correct time-text regardless of daylight savings issues, etc etc.


Handy related mysql tip:

On almost all servers, mysql also needs to know the tz info.

Basically the solution is, on the shell

sudo mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql

.. google more about it.

Fattie
  • 27,874
  • 70
  • 431
  • 719
-4

I solved this using moment.js (http://momentjs.com/docs/)

var moment = require('moment');
var offset = moment().utcOffset();
console.log(''.concat(offset < 0 ? "-" : "+",moment(''.concat(Math.abs(offset/60),Math.abs(offset%60) < 10 ? "0" : "",Math.abs(offset%60)),"hmm").format("HH:mm")));

------Edited--------

I found a better solution using moment.js. Just use moment().format('Z')

which gives the output :

+05:30

Malith
  • 685
  • 1
  • 8
  • 14
  • 3
    you can also use `moment().format('Z')` to get the same result. – Roland Starke Aug 12 '16 at 12:12
  • 3
    This gives you the current offset in your current timezone but this may vary for part of the year due to DST changes. If in doubt, always use/store UTC date/times plus the timezone identifier and then convert to local as late as possible. This way you can handle crossing DST changes. See my answer for more details. – Tim Aug 23 '17 at 13:43