2

I'm using JavaScript and trying to get GMT+0/UTC+0 time (otherwhise called Zulu time) in Unix format.

I've managed to get my local time in Unix format like this:

var datetime = new Date()
var unixtime = Math.floor(Number(datetime/1000));

but when I try to do the same with UTC time...

var datetime = new Date()
var year = datetime.getUTCFullYear()
var month = datetime.getUTCMonth()
var day = datetime.getUTCDate()
var hours = datetime.getUTCHours()
var minutes = datetime.getUTCMinutes()
var seconds = datetime.getUTCSeconds()
var unixtime = (Date.UTC(year,month,day,hours,minutes,seconds,00)/1000);

it fails. I simply get my local time in Unix format.

You can run it live here: http://jsfiddle.net/wC8XH/1/ (Also on pastebin: http://pastebin.com/uDD5zUah)

This is an example of output:

2012-01-30 23:15:19 = 1327958119
2012-01-30 21:15:19 = 1327958119

Doing:

date -d "2012-01-30 21:15:19" +%s

on Linux gives me 1327950919, not 1327958119. The difference is 7200 seconds, which is 2 hours, which is my timezone (+0200).

So I can get UTC+0 time if I simply want it in human readable format but when I request Date.UTC to convert that into Unix format, it instead chooses to convert my local time.

Am I missing something?

jsmith6
  • 39
  • 8

2 Answers2

3

Yes, you have the problem upside down.

Javascript is always telling you the number of seconds in "Unix format" as UTC or GMT. Because Unix always works internally in UTC or GMT. It doesn't make sense to speak about the "Unix time" without it being UTC.

So your two Javascript code fragments are finding out the same correct answer (What's the current "unix time"?) in a simple way and a very long-winded complicated way, that's why they give the same result.

... and the date command is locale sensitive. In your locale, you have a 2 hour offset, so it assumes your date string has a 2 hour offset. You can tell it not to behave that way by using the -u flag, which means you promise your strings are in UTC time.

Here are some examples, by setting the TZ environment variable the apparent time zone of the provided strings is altered (the values of TZ shown are for a common Unix timezone file, the names available on your specific system may vary).

$ TZ="America/New_York" date -d "2012-01-30 21:15:19" +%s
1327976119
$ TZ="Europe/Paris" date -d "2012-01-30 21:15:19" +%s
1327954519
$ date -u -d "2012-01-30 21:15:19" +%s
1327958119
tialaramex
  • 3,761
  • 1
  • 21
  • 23
2

First of all, as @tialaramex already stated, both JavaScript code snippets are correct, so you should prefer the much shorter one.

The problem is with Linux date command. When you pass a date, it interprets it in your current time zone, not in UTC! Look:

$ date -d "2012-01-30 21:15:19" +%s
1327954519
$ scala
scala> new java.util.Date(1327954519 * 1000L)
res0: java.util.Date = Mon Jan 30 21:15:19 CET 2012

I live in CET, note that date output is different than yours.

UPDATE: following the great suggestion of @derobert below in comments you can specify the time zone explicitly when invoking date:

$ date -d "2012-01-30 21:15:19+0000" +%s
1327958119
$ scala
scala> new java.util.Date(1327958119 * 1000L)
res0: java.util.Date = Mon Jan 30 22:15:19 CET 2012

21:15 in UTC is 22:15 CET, everything in order.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 1
    Well, you just have to specify the time zone to `date`, e.g., `date -d "2012-01-30 21:15:19 +0000" +%s`, `date -d "2012-01-30 21:15:19 UTC" +%s`, and `date -u -d "2012-01-30 21:15:19 Z"` all work. Please feel welcome—no, encouraged—to add this to your answer. – derobert Jan 31 '12 at 18:33
  • @derobert: I suspected there must be a way to specify the time zone to `date`, thanks! I updated my answer. – Tomasz Nurkiewicz Jan 31 '12 at 18:43
  • So, let me get this straight. When I tell a JavaScript interpreter to conver the string '2012-01-30 23:15:19 +0200' into Unix time, it first sees that it should be '2012-01-30 21:15:19 +0000' and then converts it into 1327958119, right? – jsmith6 Jan 31 '12 at 23:23