Julián Yuste
Julián Yuste

Reputation: 1472

Working with dates in breeze

I'm having some trouble working with dates.

I have an object with a date field:

public DateTime FechaInicio{get; set;}

This definition generates the following field in the database:

FechaInicio datetime not null

Making the request to the web service I get the date ( in the JSON ) in the following format:

"FechaInicio": "1982-12-02T00: 00:00"

And calling FechaInicio() on tne entity returns a javascript Date object.

Creating a new entity I get the following value:

createPalanca var = function () {
    MetadataStore var = manager.metadataStore;
    metadataStore.getEntityType palancaType = var ("Toggle");
    palancaType.createEntity newPalanca = var ();
    manager.addEntity (newPalanca);

    //Here: newPalanca.FechaInicio () has the value in this format: 1355313343214
    //Expected Date object here
    newPalanca return;
};

After all, my real question is: What format should I use to assign new values ​​to date type fields?

Edit:

After doing some tests, I noticed that if I assign a Date object to the property, everything seems fine until we got to this line:

saveBundleStringified var = JSON.stringify (saveBundle);

saveBundle content is:

FechaInicio: Thu Dec 20 2012 00:00:00 GMT+0100 (Hora estándar romance)

and the saveBundleStringified:

"FechaInicio": "2012-12-19T23:00:00.000Z" <- I guess this is utc format

What finally is stored in the database is: 2012-12-19 23:00:00.0000000

When the result of the call to SaveChanges are returned , they are merged with the entities in cache at the function updateEntity which does this check: if (!core.isDate(val)) that returns false. As a consequence it is created a new Date object with the wrong date:

function fastDateParse(y, m, d, h, i, s, ms){ //2012 12 19 23 00 00 ""
    return new Date(y, m - 1, d, h || 0, i || 0, s || 0, ms || 0);
}

Correct me if I'm wrong, but I think that's the problem.

Upvotes: 2

Views: 2284

Answers (3)

Jay Traband
Jay Traband

Reputation: 17052

Sorry for taking so long...

There were bugs with Breeze's DateTime timezone serialization and the default DateTime values used for newly constructed entities with non-nullable date fields. These are fixed as of v 0.77.2. Please confirm if this set of fixes works for you.

And thanks for finding these.

And to answer your question, all date properties on your object should be set to javascript Dates. Breeze should handle all of the serialization issues properly.

Upvotes: 4

Ward
Ward

Reputation: 17863

Dates always scare me. My immediate instinct is that the browser and server are not on the same TimeZone; how that could be I don't know. In any case, it's bound to happen and I recall all kinds of fundamental problems with coordinating client and server on datetime. I think the usual recommendation has always been to keep everything in UTC and adjust what you display to the user in local time.

I rather doubt this is a helpful answer. I'm not sure what part Breeze should play in resolving this. Would welcome a suggestion that we can circulate and build consensus around.

Also can you clarify this statement:

When the result of the call to SaveChanges are returned , they are merged with the entities in cache at the function updateEntity which does this check: if (!core.isDate(val)) that returns false. As a consequence it is created a new Date object with the wrong date

What do you mean by "the wrong date"? And are you saying that Breeze thinks the incoming date value is in an invalid format (as opposed to being a date other than the one you expected)?

Yes, @Sascha, Breeze is using the Web Api standard for JSON formatting (Json.Net) and it is set for ISO8601 format as opposed to the wacky Microsoft format (which escapes me as I write this).

Upvotes: 1

Sascha Herrmann
Sascha Herrmann

Reputation: 552

Breeze/Web Api seem to need the dates in some special format (ISO8601). Any other format did not work for me. moment.js solved the problem for me with setting and reading. Formatting is also nicely done if you use Knockout to display the date with a special binding.

entity.someDate(moment().utc().toDate()) // example

and it works.

You could also use this:

Date.prototype.setISO8601 = function(string) {
        var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
            "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
            "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
        var d = string.match(new RegExp(regexp));

        var offset = 0;
        var date = new Date(d[1], 0, 1);

        if (d[3]) {
            date.setMonth(d[3] - 1);
        }
        if (d[5]) {
            date.setDate(d[5]);
        }
        if (d[7]) {
            date.setHours(d[7]);
        }
        if (d[8]) {
            date.setMinutes(d[8]);
        }
        if (d[10]) {
            date.setSeconds(d[10]);
        }
        if (d[12]) {
            date.setMilliseconds(Number("0." + d[12]) * 1000);
        }
        if (d[14]) {
            offset = (Number(d[16]) * 60) + Number(d[17]);
            offset *= ((d[15] == '-') ? 1 : -1);
        }

        offset -= date.getTimezoneOffset();
        time = (Number(date) + (offset * 60 * 1000));
        this.setTime(Number(time));
    };

Upvotes: 0

Related Questions