0
var input = "/Date(1450399658897)/";
var m_utc = moment.utc(input);

My impression is that the whole point of moment.utc(...) parses the data as if it were a UTC date. Yet it seems to actually parse it as a local time, at least when sending in the lousy ASP.NET JSON date format.

See the JS Fiddle here:
http://jsfiddle.net/6g0nmr3e/5

If you live in a timezone with no UTC offset it won't be too helpful, but it does demonstrate that the value is 2015-12-17 19:47 Z. However moment.js, instead of parsing as UTC, parses as local then converts that value to UTC giving 2015-12-18 00:47 Z.

Am I misunderstanding moment.utc(...)? Or should I report this as a bug?

Clyde
  • 8,017
  • 11
  • 56
  • 87
  • Actually, the value you gave, `1450399658897` is indeed equivalent to `2015-12-18T00:47:38.897Z`. You can see it at [epochconverter.com](http://www.epochconverter.com/), or in your own fiddle if you use `toISOString` instead of `toString` on the `parseddate` variable. Moment is doing the right thing. – Matt Johnson-Pint Dec 18 '15 at 02:32
  • Hmm.....could be a problem on the ASP.NET side then? I'll investigate further – Clyde Dec 18 '15 at 13:05
  • 1
    Somewhere you probably have a `DateTime` with `DateTimeKind.Unspecified` whose value is not UTC based. Either it originates from `DateTime.Now` and is stored then retrieved, or it is going through time zone conversions. Best bet is to use `DateTimeOffset` instead, and use JSON.Net with ISO8601 instead of the lousy older format. WebAPI does this automatically BTW. – Matt Johnson-Pint Dec 18 '15 at 15:06
  • If I did misread the output then this is almost certainly the problem. I believe entity framework pulls it from in Unspecified format, although I've seen other Stack Overflow questions for altering that default. I'll confirm this next week. – Clyde Dec 19 '15 at 03:56
  • Try my approach [from this answer](http://stackoverflow.com/a/19301623/634824). :-) – Matt Johnson-Pint Dec 19 '15 at 04:11

1 Answers1

1

So the root problem was that I didn't read the javascript date output properly. I interpreted this

Thu Dec 17 2015 19:47:38 GMT-0500 

as this

(Thu Dec 17 2015 19:47:38 GMT)-0500 

when it is actually this

(Thu Dec 17 2015 19:47:38) GMT-0500 

The date was coming from the server incorrectly. Matt's intuition is correct is that it's DateTimeKind.Unspecified datetime fields coming from entity framework. Unfortunately, there does not seem to be any good solution to this problem. The linked solution only works for full entities being generated and is no help for projected objects. There does not seem to be an event hook for all materializations.

In my particular case I am creating a model class for a MVC view, so I'm adjusting the setter to look like this:

private DateTime _TimestampUTC;
public DateTime TimestampUTC
{
    get { return _TimestampUTC; }
    set
    {
        switch (value.Kind)
        {
            case DateTimeKind.Unspecified:
                _TimestampUTC = DateTime.SpecifyKind(value, DateTimeKind.Utc);
                break;
            case DateTimeKind.Local:
                _TimestampUTC = value.ToUniversalTime();
                break;
            case DateTimeKind.Utc:
                _TimestampUTC = value;
                break;
        }
    }
}

I'm also generating my POCO entities with T4 so I'm doing this with those as well to avoid the reflection overhead given in most other answers you'll see. However the 'best' solution would be some way to specify the DateTimeKind of an entity field and have that carry through any projection made on that field, including anonymous types. But as best as I can tell this is not possible with current versions of EF. As it is, I'll have to remember to do this for each and every UTC DateTime field on all models being pushed to the javascript client.

Clyde
  • 8,017
  • 11
  • 56
  • 87