Reputation: 30501
I am using Backbone.js sync to store my models to a database.
The problem is that Backbone.js sync converts Date from my local timezone format into a UTC Date. I have traced this back to use of JSON.stringify
within Backbone.js sync:
params.data = JSON.stringify(model.toJSON());
As an example what happens here:
>>> var a = {myDate: new Date();}
>>> JSON.stringify(a);
>>> a
"{"myDate":"2012-05-04T21:58:34.734Z"}"
As such, when I use Backbone.js sync again to retrieve the same resource, my timezone is converted to UTC. I would wish instead to have the original, local timezone preserved.
For me it is OK that the data is stored to the database as UTC, just as long as I somehow manage to convert it back to the local timezone.
All help is approciated.
Upvotes: 1
Views: 3757
Reputation: 434765
All communication with the server should be done in UTC so JSON.stringify
is doing what you want it to. Your missing piece seems to be converting the UTC timestamp that you get from the server into the browser's local time zone.
You can intercept the server's JSON before it goes into your model by providing a parse
implementation in your model:
parse
model.parse(response)
parse is called whenever a model's data is returned by the server, in fetch, and save. The function is passed the raw
response
object, and should return the attributes hash to be set on the model. The default implementation is a no-op, simply passing through the JSON response. Override this if you need to work with a preexisting API, or better namespace your responses.
That will get you an object {myDate: '2012-05-04T21:58:34.734Z'}
in response
so you just have to convert that to your local timezone. A quick combination of Date.parse
and new Date
will give you a Date object in the browser's timezone:
var d = new Date(Date.parse(response.myDate));
// Fri May 04 2012 14:58:34 GMT-0700 (PDT)
If you want Date objects in your model then you just need to return the Date wrapped in an object:
return { myDate: d };
or, if response
has more things you could:
response.myDate = d;
return response;
// or if you don't want to modify response
return _({}).extend(response, { myDate: d });
If you for some reason you wanted an ISO-8601 string in the browser's timezone then you could easily build one using the standard Date methods; I think you'd be better off keeping the Date object though, that's far more useful than the string.
Upvotes: 10