3

I've read this question: How do you convert a JavaScript date to UTC?

and based on this I implemented this conversion in a dateTools module as follows:

[Update]

var dt, utcTime;
dt = new Date();
utcTime = new Date(Date.UTC(dt.getFullYear(), 
                                        dt.getMonth(), 
                                        dt.getDate(), 
                                        dt.getHours(), 
                                        dt.getMinutes(), 
                                        dt.getSeconds(), 
                                        dt.getMilliseconds()));

Now I'd like to write unit tests. My idea was to check whether the result is actually in UTC, but I don't know how.

All the toString, toUTCString and similar methods seem to be identical for the input (non UTC) and output (UTC) date.

Only the result of the getTime method differs.

Is there a way to check wheter a date is UTC in javascript? If not, is there a better idea to unit test this?

To give more context:

Only converting the it to a UTC string is not that helpful, because in the next step the date is sent to an Asp.net service and therefore converted to a string like:

'/Date([time])/'

with this code

var aspDate = '/Date(' + date.getTime() + ')/';
Community
  • 1
  • 1
stefan.s
  • 3,489
  • 2
  • 30
  • 44

2 Answers2

10
var aspDate = '/Date(' + date.getTime() + ')/';

This outputs the internal UNIX epoch value (UTC), which represents a timestamp. You can use the various toString methods to get a more verbose string representation of that timestamp:

  • .toString() uses the users timezone, result is something like "Fri Jan 25 2013 15:20:14 GMT+0100" (for me, at least, you might live in a different timezone)
  • .toUTCString() uses UTC, and the result will look like "Fri, 25 Jan 2013 14:20:15 GMT"
  • .toISOString() uses UTC, and formats the datestring according to ISO: "2013-01-25T14:20:20.061Z"

So how do we construct the time value that we want?

  • new Date() or Date.now() result in the current datetime. No matter what the user's timezone is, the timestamp is just the current moment.
  • new Date(year, month, …) uses the users timezone for constructing a timestamp from the single values. If you expect this to be the same across your user community, you are screwed. Even when not using time values but only dates it can lead to odd off-by-one errors.
    • You can use the setYear, setMonth, … and getYear, getMonth … methods to set/get single values on existing dates according to the users timezone. This is appropriate for input from/output to the user.
    • getTimezoneOffset() allows you to query the timezone that will be used for all these
  • new Date(timestring) and Date.parse cannot be trusted. If you feed them a string without explicit timezone denotation, the UA can act random. And if you want to feed a string with a proper format, you will be able to find a browser that does not accept it (old IEs, especially).
  • Date.UTC(year, month, …) allows you to construct a timestamp from values in the UTC timezone. This comes in handy for input/output of UTC strings.
    • Every get/set method has a UTC equivalent which you can also use for these things.

You can see now that your approach to get the user-timezone values and use them as if they were in UTC must be flawed. It means either dt or utcTime has the wrong value, although using the wrong output method may let it appear correct.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • You are proposing to just use getTime without converting it to UTC. But how should I know the timezone on the server then? – stefan.s Jan 25 '13 at 14:43
  • 1
    `getTime` returns milliseconds since 1 January 1970 00:00 UTC of the timestamp you have. Which timezone would you need to know? – Bergi Jan 25 '13 at 14:48
  • Oh, I missed the point that getTime always returns UTC. But doesn't that mean, that the question / answer to this question is wrong: http://stackoverflow.com/questions/948532/how-do-you-convert-a-javascript-date-to-utc. Sorry, but I'm confused. – stefan.s Jan 25 '13 at 14:54
  • You mean the ninety-votes-answer? Yes, that is nonsense. You need it only when use the wrong output method. – Bergi Jan 25 '13 at 15:03
  • thanks. I learned a lot. Looks like I asked the wrong question. I guess I need to rethink the dateTools module... – stefan.s Jan 25 '13 at 15:13
0
  • getTimezoneOffset

    Syntax: object.getTimezoneOffset( ) This method returns the difference in minutes between local time and Greenwich Mean Time. This value is not a constant, as you might think, because of the practice of using Daylight Saving Time.

i.e.

var myDate = new Date;
var myUTCDate = new Date(myDate - myDate.getTimezoneOffset() * 60000);
alert(myUTCDate);

note: 60000 is the number of milliseconds in a minute;

ic3b3rg
  • 14,629
  • 4
  • 30
  • 53
  • The TimezoneOffset is equal for the converted and non converted date – stefan.s Jan 25 '13 at 13:54
  • I already know how to convert the date to UTC. But how could I write a unit test for it? – stefan.s Jan 25 '13 at 14:01
  • @stefan.s: You do not need to convert a date to UTC. You just need to output the timestamp it represents as UTC. Please show us how you "convert" it. – Bergi Jan 25 '13 at 14:03
  • @stefan.s where are your date values originating from? – ic3b3rg Jan 25 '13 at 14:20
  • @ic3b3rg In production: could be anywhere, different timezones between client and server should be excpected. For the unit tests: currently UTC+1, but the tests shouldn't need a specific time zone, they should just run anywhere. – stefan.s Jan 25 '13 at 14:23