I think this is a bug.
What is the current behavior?
Currently I have a nice date object which logs out to
Fri Apr 29 2016 13:33:00 GMT+0100 (BST)
When this object is then POSTED via $http the following is observed in the network requests..
2016-04-28T12:33:00.000Z
So the $http object subtracts an hour and effectively removes the British Summer Time BST from the time. So this is stored in the database without this offset. When we immediately read this date it comes back but how can the system know that we need to add back the hour ?
So imagine also of the user is in another timezone..say 5 hours ahead then the system will subtract 5 hours...Time is sensitive to the context in which it is created. in other words the timezone information should not be removed.
I am seeing this in Chrome. Angular 1.4.2
This is not something Angular-specific. It is standard JSON.stringify
behavior.
Basically, when posting data, $http
converts it to JSON (via JSON.stringify()
). In JavaScript, the JSON representation of a Date object is its ISO-8601 form (which is what you see in the network tab).
A Date object doesn't have a timezone information anyway, so there is no information stripped. The current locale (which is totally independent of the date represented by Date objects) has a timezone offset and the browser formats the date according to that offset when console.log
ging it.
Closing as this is not an issue with Angular.
@gkalpak First I think it is not correct saying Date object does not have a timezone information. When we create a date by new Date(), the time zone information is the local zone by default. A Date object has getTimezoneOffset
and toISOString
methods. When called these methods returns zone value, it is nothing browser is printing nice for us, they are actual values in the Date object.
new Date().getTimezoneOffset()
-330
new Date().toISOString()
"2018-12-04T05:40:37.399Z"
Secondly, JSON.stringify()
also does not strip zone value, the following is what we saw in browser console and it is the same, the browser is not printing anything nice for us.
JSON.stringify({d:new Date()})
"{"d":"2018-12-04T05:42:08.973Z"}"
So I still believe is that if the API render an ISO date which does not have those milliseconds value and UI is using some datepicker which only picks a date and change date then Angular when sending the date back converting into ISO format it will not have milliseconds value.
First I think it is not correct saying Date object does not have a timezone information.
I still think it is correct to say that :grin: A Date
object _"represents a single moment in time [...] based on a time value that is the number of milliseconds since 1 January 1970 UTC"_ (source: MDN). So, basically each Date
instance only knows about this one value and all other representations of it are induced based on that info plus locale/system state (such as timezone offset).
A Date object has
getTimezoneOffset
andtoISOString
methods.
These are methods on the Date
prototype (source: MDN), not of the Date
objects (aka instances) themselves.
More specifically, the value of getTimezoneOffset() depends on the current locale (host system settings). This is the reason why there is no equivalent setTimezoneOffset()
method and why all Date
objects on the same system return the same value for getTimezoneOffset()
, e.g.:
const d1 = new Date('December 15, 2018 12:34:56'); // No timezone; uses the current system locale.
const d2 = new Date('December 15, 2018 12:34:56 GMT+10'); // Uses GTM+10 as timezone.
d1.getTimezoneOffset() === d2.getTimezoneOffset(); // true
So, the timezone info specified in a date string representation passed to Date
is only used to parse that string and map it to a specific moment in time as described above. The resulting Date
object does not know anything about timezones :smiley:
The toISOString() method does not print timezone info as you suggested. It just adds Z
at the end, which denotes UTC
.
Secondly,
JSON.stringify()
also does not strip zone value
As explained above, it uses toISOString()
, which expresses the date value in UTC (thus appending Z
at the end to indicate that). There is no timezone info in the returned string.
So I still believe is that if the API render an ISO date which does not have those milliseconds value and UI is using some datepicker which only picks a date and change date then Angular when sending the date back converting into ISO format it will not have milliseconds value.
I have no idea what milliseconds have to do with it. We were talking about timezone info.
Again, this has nothing to do with AngularJS. This is how the built-in objects (such as Date
and JSON
) interact with each other.
Most helpful comment
I still think it is correct to say that :grin: A
Date
object _"represents a single moment in time [...] based on a time value that is the number of milliseconds since 1 January 1970 UTC"_ (source: MDN). So, basically eachDate
instance only knows about this one value and all other representations of it are induced based on that info plus locale/system state (such as timezone offset).#
These are methods on the
Date
prototype (source: MDN), not of theDate
objects (aka instances) themselves.More specifically, the value of getTimezoneOffset() depends on the current locale (host system settings). This is the reason why there is no equivalent
setTimezoneOffset()
method and why allDate
objects on the same system return the same value forgetTimezoneOffset()
, e.g.:So, the timezone info specified in a date string representation passed to
Date
is only used to parse that string and map it to a specific moment in time as described above. The resultingDate
object does not know anything about timezones :smiley:The toISOString() method does not print timezone info as you suggested. It just adds
Z
at the end, which denotesUTC
.#
As explained above, it uses
toISOString()
, which expresses the date value in UTC (thus appendingZ
at the end to indicate that). There is no timezone info in the returned string.#
I have no idea what milliseconds have to do with it. We were talking about timezone info.
Again, this has nothing to do with AngularJS. This is how the built-in objects (such as
Date
andJSON
) interact with each other.