0

I have this method in the C# (server) side:

protected double GetAccountTime()
{
    return ((DateTime)unit.SomeMethod(DateTime.UtcNow))
            .Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))
            .TotalMilliseconds;
}

My local machine time is Eastern, but my application's account time is Mountain. So I want to change it to Eastern to Mountain time. unit.SomeMethod(...) just takes the current local time (Eastern) and converts it to account time (Mountain).

In the Javascript side:

var now = new Date(<%=GetAccountTime()%>);
alert(now);//doesn't consider the time to be UTC, need to convert
var now_utc = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
alert("UTC:  " + now_utc);

The first alert statement gives me Thu Jun 12 2014 09:30:42 GMT-0400 (Eastern Standard Time) which is incorrect. I convert the time to UTC, so second alert statement gives me UTC: Thu Jun 12 2014 13:30:42 GMT-0400 (Eastern Standard Time). This is correct as far as time goes, but the time zone is still Eastern. Does anyone why and how can I fix this?

What my application does (at request of @JonSkeet):

  • It will get the time of the account time for different recorded footage (possibly in different locations).
  • There will be a timeline-like cursor which needs account time (not local time).
  • There will be options which will send the time back to the server side, so knowing the correct offset will make this easier.

1 Answers1

3

A Date object doesn't have any concept of a time zone. It always represents a number of milliseconds since the Unix epoch.

You don't need to do any conversions - you've got the right point in time. (Indeed, there's no sense in which you can convert between time zones with Date, as it's just a point in time.)

If you're concerned about the string representation, you can call toUTCString(). The toString() function will always use the system local time.

For example, in a Chrome console:

> var now = new Date();
> now.toString()
"Thu Jun 12 2014 20:35:33 GMT+0100 (GMT Daylight Time)"
> now.toUTCString()
"Thu, 12 Jun 2014 19:35:33 GMT"

EDIT: Now we have a bit more information:

  • If you need to display particular instants in time in a particular time zone, I suggest you do the conversion to text at the server side
  • If you need to send a local time back to the server, I suggest you do so in text
  • If you possibly can, I'd avoid having the idea of an "account time zone" anyway - try to store everything as UTC if possible. By all means render the values in a particular time zone, which the user should be able to control, but you should try to avoid doing any arithmetic using time zones.

If you're going to do more work on the .NET side, you might want to look at my Noda Time project, too.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • The GMT offset is actually needed for the application I'm working on. Is there really no way (or work around) for a `Date` object to update the timezone? – But I'm Not A Wrapper Class Jun 12 '14 at 19:51
  • 2
    @CyberneticTwerkGuruOrc: You've missed the point - there *is* no time zone in a `Date` object. If you need the offset from UTC to Mountain Time, that's relatively tricky - as you'd be relying on a cross-browser way of getting at that time zone. If you can explain (in the question) more about what you're trying to achieve, we may be able to help you more. – Jon Skeet Jun 12 '14 at 19:53
  • Updated my opening post. It's still a bit vague, but I think that should cover the reasons why I need to change the timzone (and why offsets matter). I understood that `Date` is essentially milliseconds, but I was just wondering if there was still a way to change the offset. – But I'm Not A Wrapper Class Jun 12 '14 at 20:21
  • +1 - See also [How to initialize javascript date to a particular timezone](http://stackoverflow.com/a/15171030/634824). – Matt Johnson-Pint Jun 12 '14 at 20:27
  • @CyberneticTwerkGuruOrc: That's like saying "I know strings don't have colours, but I still want to change this string from red to blue." If you want a data type with an offset, you need something other than `Date`. I'll edit my answer. – Jon Skeet Jun 12 '14 at 20:33
  • Not exactly @JonSkeet. Since the `Date` object does contain an offset in the string representation (which I assume it gets because it contain the offset in minutes), it's odd that they don't have a set method for offset (or timezone). It has a set method for nearly everything else. It is so outlandish to expect a datetime-like object to carry a timezone/offset property? – But I'm Not A Wrapper Class Jun 12 '14 at 20:39
  • @CyberneticTwerkGuruOrc: No, it happens to print an offset using the local time zone - but *always* the local time zone. There's no notion of an offset or time zone in the data itself, as I keep saying. It's a bit like printing an `int` - by default, it always comes out in decimal. You can print an `int` value in hex instead (like calling `toUTCString`) but that doesn't mean that the base is part of the value itself. It's just a different representation. As for expectations of a datetime-like object... well, I'd try to avoid making assumptions, based on how awful almost all date/time APIs are. – Jon Skeet Jun 12 '14 at 20:42