[CLOSED] Ext.util.Format.date fails if Date's millisencond 'length' is lower than 3

  1. #1

    [CLOSED] Ext.util.Format.date fails if Date's millisencond 'length' is lower than 3

    Example 1 - Fails

    The Date's millisecond equals 27
    Ext.util.Format.date('2013-05-15T17:23:53.27-03:00', 'd/m/Y H:i:s')
    Results: NaN/NaN/0NaN NaN:NaN:NaN



    Example 2 - Works

    The Date's millisecond equals 027
    Ext.util.Format.date('2013-05-15T17:23:53.027-03:00', 'd/m/Y H:i:s')
    Results: 15/05/2013 17:23:53



    Any ideas to overcome this issue?

    Thanks in advance
    Last edited by Baidaly; May 17, 2013 at 6:33 PM. Reason: [CLOSED]
  2. #2
    Hello!

    Couldn't reproduce, can you say browser and Ext.NET version?
  3. #3
    Hi everybody,

    I was able to reproduce it in IE9, but not in FireFox and Chrome.

    Well, the problem is the following.

    Let's take a look at the Ext.util.Format.date doc:
    http://docs.sencha.com/extjs/4.2.0/#...at-method-date

    It says:
    If a string is passed, it is converted to a Date by the Javascript's built-in Date.parse method.
    Ext.util.Format.date
    date: function (v, format) {
        if (!v) {
            return "";
        }
        if (!Ext.isDate(v)) {
            v = new Date(Date.parse(v));
        }
        return Ext.Date.dateFormat(v, format || Ext.Date.defaultFormat);
    }
    So, your test case can be written this way.
    Date.parse('2013-05-15T17:23:53.27-03:00');
    Chrome and FireFox are able to parse such a string, but IE9 is not. Since the Date.parse is a built-in function in IE JavaScript engine, I don't think we can overcome it.

    But you can use the Ext.Date.parse method.
    Ext.Date.parse('2013-05-15T17:23:53.27-03:00', 'c');
  4. #4
    The following code exemplifies my real world scenario. The data flushed by ResultStore is "mal formatted". The Date's millisecond does not have a XXX format.

    Click image for larger version. 

Name:	ErrorStoreResult 001.png 
Views:	33 
Size:	4.2 KB 
ID:	6239
    <!DOCTYPE html>
    <html>
    <head runat="server">
    </head>
    <body>
        <ext:ResourceManager runat="server" />
        <ext:GridPanel Title="Records" Frame="false" Width="500" runat="server">
            <Store>
                <ext:Store runat="server">
                    <Proxy>
                        <ext:AjaxProxy Url="/Example/LoadFakeRecords/">
                            <ActionMethods Read="POST" />
                            <Reader>
                                <ext:JsonReader Root="data" />
                            </Reader>
                        </ext:AjaxProxy>
                    </Proxy>
                    <Model>
                        <ext:Model runat="server">
                            <Fields>
                                <ext:ModelField Name="ID" Type="String" />
                                <ext:ModelField Name="Birthdate" Type="Date" DateFormat="d/m/Y H:i:s">
                                    <Convert Handler="return Ext.util.Format.date(value, 'd/m/Y H:i:s');" />
                                </ext:ModelField>
                            </Fields>
                        </ext:Model>
                    </Model>
                    <Sorters>
                        <ext:DataSorter Property="Common" Direction="ASC" />
                    </Sorters>
                </ext:Store>
            </Store>
            <ColumnModel runat="server">
                <Columns>
                    <ext:RowNumbererColumn runat="server" />
                    <ext:Column Text="ID" DataIndex="ID" runat="server"/>
                    <ext:Column Text="Birthdate" DataIndex="Birthdate" Width="300" runat="server"/>
                </Columns>
            </ColumnModel>
        </ext:GridPanel>
    </body>
    </html>
    public class ExampleController : System.Web.Mvc.Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        public StoreResult LoadFakeRecords()
        {
            List<Person> lst = new List<Person>();
    
            lst.Add(new Person
            {
                ID = 1,
                Birthdate = new DateTime(2013, 05, 17, 10, 11, 12, 13),
            });
    
            lst.Add(new Person
            {
                ID = 2,
                Birthdate = new DateTime(2013, 05, 17, 10, 11, 12, 200),
            });
    
    
            return new StoreResult(lst, lst.Count());
        }
    }
    
    public class Person
    {
        public int ID { get; set; }
    
        public DateTime Birthdate { get; set; }
    }


    It's possible to overcome this issue by defining a new StoreResult class, that uses JSONDateTimeJsonConverter to flush Date's millisecond formatted accordingly.

    Click image for larger version. 

Name:	ErrorStoreResult 002.png 
Views:	27 
Size:	4.2 KB 
ID:	6240

    public class SmartStoreResult : StoreResult
    {
        public SmartStoreResult(object data, int totalCount) :
            base(data, totalCount) { }
    
        public override void ExecuteResult(ControllerContext context)
        {
            NodeCollection nodes = this.Data as NodeCollection;
            StoreResponseData storeResponse = new StoreResponseData(this.IsTree || nodes != null);
            if (nodes != null)
            {
                storeResponse.Data = ((NodeCollection)this.Data).ToJson();
            }
            else
            {
                storeResponse.Data = JSON.Serialize(this.Data, new List<JsonConverter> { new JSONDateTimeJsonConverter { RenderMilliseconds = true } });
            }
    
            storeResponse.Total = this.Total;
            storeResponse.Success = this.Success;
            storeResponse.Message = this.Message;
            storeResponse.Return();
        }
    }
    public class ExampleController : System.Web.Mvc.Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        public SmartStoreResult LoadFakeRecords()
        {
            List<Person> lst = new List<Person>();
    
            lst.Add(new Person
            {
                ID = 1,
                Birthdate = new DateTime(2013, 05, 17, 10, 11, 12, 13),
            });
    
            lst.Add(new Person
            {
                ID = 2,
                Birthdate = new DateTime(2013, 05, 17, 10, 11, 12, 200),
            });
    
    
            return new SmartStoreResult(lst, lst.Count());
        }
    }


    I would like to know what do you think about this approach.

    Thanks in advance
  5. #5
    Quote Originally Posted by Daniil View Post
    I was able to reproduce it in IE9, but not in FireFox and Chrome.
    Quote Originally Posted by Baidaly View Post
    Couldn't reproduce, can you say browser and Ext.NET version?
    I tested on IE9 using the latest version of Ext.Net (SVN)
  6. #6
    Well, your approach is good.

    But since this works
    Ext.Date.parse('2013-05-15T17:23:53.27-03:00', 'c');
    I would do it in a different way.

    First of all, please note that these Model's settings
    Type="Date" DateFormat="d/m/Y H:i:s"
    doesn't make sense if you use a ModelField's Convert. It just sets up some internal Convert handler which you override with your custom one.

    Also this setting
    DateFormat="d/m/Y H:i:s"
    expects a .NET date time format string. Then it converts it to ExtJS/PhP date time format string.

    I would specify the following ModelField.
    <ext:ModelField Name="Birthdate">
        <Convert Handler="return Ext.Date.parse(value, 'c');" />
    </ext:ModelField>
    After this you are getting Date objects in the Store, not strings. For me it is more usable. You can always convert it to string if needed.

    To show dates in a GridPanel, I would use a DateColumn.
    <ext:DateColumn 
        runat="server" 
        Text="Birthdate" 
        DataIndex="Birthdate" 
        Width="300" 
        Format="dd/MM/yyyy HH:mm:ss" />
  7. #7
    Thank you Danill. it works like a charm.
  8. #8
    Daniil, in addition i would like to provide a running example that uses your approach, it may be useful for someone.

    Please mark this thread as closed.

    <!DOCTYPE html>
    <html>
    <head runat="server">
    </head>
    <body>
        <ext:ResourceManager runat="server" />
        <ext:GridPanel Title="Records" Frame="false" Width="500" runat="server">
            <Store>
                <ext:Store runat="server">
                    <Proxy>
                        <ext:AjaxProxy Url="/Example/LoadFakeRecords/">
                            <ActionMethods Read="POST" />
                            <Reader>
                                <ext:JsonReader Root="data" />
                            </Reader>
                        </ext:AjaxProxy>
                    </Proxy>
                    <Model>
                        <ext:Model runat="server">
                            <Fields>
                                <ext:ModelField Name="ID" Type="String" />
                                <ext:ModelField Name="Birthdate" Type="Date" />
                            </Fields>
                        </ext:Model>
                    </Model>
                </ext:Store>
            </Store>
            <ColumnModel runat="server">
                <Columns>
                    <ext:RowNumbererColumn runat="server" />
                    <ext:Column Text="ID" DataIndex="ID" runat="server" />
                    <ext:DateColumn Text="Birthdate" DataIndex="Birthdate" Width="300" Format="dd/MM/yyyy HH:mm:ss" runat="server" />
                </Columns>
            </ColumnModel>
        </ext:GridPanel>
    </body>
    </html>
    public class ExampleController : System.Web.Mvc.Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        public StoreResult LoadFakeRecords()
        {
            List<Person> lst = new List<Person>();
    
            lst.Add(new Person
            {
                ID = 1,
                Birthdate = new DateTime(2012, 05, 17, 10, 11, 12, 13),
                Active = true
            });
    
            lst.Add(new Person
            {
                ID = 2,
                Birthdate = new DateTime(2013, 05, 17, 10, 11, 12, 200),
                Active = false
            });
    
            return new StoreResult(lst, lst.Count());
        }
    }
    
    public class Person
    {
        public int ID { get; set; }
    
        public DateTime Birthdate { get; set; }
    
        public Nullable<bool> Active { get; set; }
    }
  9. #9
    Yes, it is nice to share a full example. Thank you!

Similar Threads

  1. Replies: 3
    Last Post: May 09, 2012, 4:28 PM
  2. Replies: 1
    Last Post: Apr 13, 2012, 1:52 PM
  3. Replies: 1
    Last Post: Nov 29, 2011, 5:11 PM
  4. [CLOSED] Error in the Ext.util.Format.date
    By ViDom in forum 1.x Legacy Premium Help
    Replies: 6
    Last Post: Sep 16, 2011, 11:42 AM
  5. Replies: 4
    Last Post: Jun 30, 2011, 3:30 PM

Posting Permissions