参考文章:(http://www.cnblogs.com/milo-xie/archive/2012/04/24/2468660.html)
一、下午在搞MVC和EXTJS的日期格式互相转换遇到了问题,我们从.NET服务器端序列化一个DateTime对象的结果是一个字符串格式,如 '/Date(1335258540000)/' 这样的字串。
整数1335258540000实际上是一个1970 年 1 月 1 日 00:00:00至这个DateTime中间间隔的毫秒数。通过javascript用eval函数可以把这个日期字符串转换为一个带有时区的Date对象,如下
用var date = eval('new ' + eval('/Date(1335258540000)/').source) 这样即可得到一个JS对象
通过alert(date)查看比较清楚。
Tue Apr 24 17:09:00 UTC+0800 2012
上面是C# JSON序列化日期自动得到的字符串,也可以通过C#写一个函数来获取这个数字,例如
1
2
3
4
5
6
7
|
public
long
MilliTimeStamp(DateTime TheDate)
{
DateTime d1 =
new
DateTime(1970, 1, 1);
DateTime d2 = TheDate.ToUniversalTime();
TimeSpan ts =
new
TimeSpan(d2.Ticks - d1.Ticks);
return
(
long
)ts.TotalMilliseconds;
}
|
通过上面的函数跟利用JSON序列化获取到的字符串中的整数是一样的。
但是,在从客户端返回服务器端的时候,日期却遇到了问题,如何将javascript的Date对象传回服务器端呢?
先通过javascript Date中的getTime()来获取到这个整数,然后服务器端对这个整数进行解析,‘构造’成一个C#的DateTime对象。思路大概是这样的,不过在逆向回去的时候却遇到了点麻烦。
public DateTime ConvertTime(long milliTime) { long timeTricks = new DateTime(1970, 1, 1).Ticks + milliTime * 10000 ; return new DateTime(timeTricks); }
通过ConvertTime得到的结果发现时间少了8个小时,这刚好是服务器的时区,东八区时间,也就是说还要加上8小时的纳秒,因为C#的时间戳单位是一千万分之一秒,一个小时3600秒,即8*3600*10000000
所以修改了ConvertTime函数,正确的如下:
1 public DateTime ConvertTime(long milliTime) 2 { 3 long timeTricks = new DateTime(1970, 1, 1).Ticks + milliTime * 10000 + TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Hours * 3600 * (long)10000000; 4 return new DateTime(timeTricks); 5 }
部分源码如下:
字段(Fields):
<ext:RecordField Name="DatedDate" DateFormat="Y/m/d"/>
<ext:RecordField Name="ExpiringDate" DateFormat="Y/m/d"/>
列模型(ColumnModel):
<ext:Column ColumnID="DatedDate" Header="起息日" DataIndex="DatedDate">
<Renderer Handler="return Ext.util.Format.date(eval('new ' + eval(value).source),'Y年m月d日')" />
</ext:Column>
<ext:Column ColumnID="ExpiringDate" Header="到期日" DataIndex="ExpiringDate" Hidden="false">
<Renderer Handler="return Ext.util.Format.date(eval('new ' + eval(value).source),'Y年m月d日')" />
</ext:Column>
异步加载:
<ext:Store ID="storeResult" runat="server" RemoteSort="true" AutoLoad="false">
<Proxy>
<ext:HttpProxy Json="true" Method="POST" Url="../metadata/WebService.asmx/QueryPagingGeneral">
</ext:HttpProxy>
</Proxy>
<AutoLoadParams>
<ext:Parameter Name="start" Value="={0}" />
<ext:Parameter Name="limit" Value="={30}" />
</AutoLoadParams>
<BaseParams>
<ext:Parameter Name="filter" Value="" Mode="Value" />
</BaseParams>
<SortInfo Field="ID" Direction="ASC" />
<Reader>
<ext:JsonReader IDProperty="ID" Root="d.Data" TotalProperty="d.TotalRecords">
<Fields>
...
</Fields>
异步调用方法(webservice):[System.Web.Script.Services.ScriptService]必须要加.
[WebMethod(EnableSession = true)]
public Paging<ProductInfo> QueryPagingGeneral(int start, int limit, string sort, string dir, string filter)
{
ImportDataService _service = new ImportDataService();
Hashtable ht = Session["QueryGeneral"] as Hashtable;
if (ht == null)
{
ht = new Hashtable();
}
ht["PageStart"] = start;
ht["PageEnd"] = start + limit;
int total = _service.GetProductCountForRemote(ht);
IList<ProductInfo> models = _service.GetProductListForRemote(ht);
foreach (ProductInfo item in models)
{
item.ProductName = "<a href='ProductDetails.aspx?pagename=general&PID=" + item.ID + "&pageindex=" + (start/limit+1) + "'>" + item.ProductName + "</a>";
}
return new Paging<ProductInfo>(models, total);
}
二、0NaN年NaN月NaN,这一问题在ie8中出现,其他版本没有出现,其他浏览器也没有出现,这是ie浏览器版本之间的兼容性问题。解决方法:
添加类型属性Type=“Date”
代码如下:
<ext:GridPanel ID="GridPanel1" runat="server" Title="报告列表</font>" Margins="0 0 5 5"
Icon="UserSuit" Region="Center" Frame="true" StripeRows="true">
<Store>
<ext:Store ID="storeResult" runat="server">
<Reader>
<ext:JsonReader IDProperty="ID">
<Fields>
<ext:RecordField Name="ID" />
<ext:RecordField Name="Title" />
<ext:RecordField Name="Author" />
<ext:RecordField Name="PublishTime" Type="Date" />
<ext:RecordField Name="ReportType" />
<ext:RecordField Name="DownloadCount" />
<ext:RecordField Name="Path" />
</Fields>
</ext:JsonReader>
</Reader>
<AutoLoadParams>
<ext:Parameter Name="start" Value="0" Mode="Raw" />
<ext:Parameter Name="limit" Value="30" Mode="Raw" />
</AutoLoadParams>
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:RowNumbererColumn Width="40px" Header="序号" Align="Center" />
<ext:Column ColumnID="Title" Header="标题" DataIndex="Title" Align="Center" Width="200px" />
<ext:Column ColumnID="Author" Header="撰写人" DataIndex="Author" Align="Center"/>
<ext:Column ColumnID="ReportType" Header="类型" DataIndex="ReportType" Align="Center" />
<ext:Column ColumnID="PublishTime" Header="发布日期" DataIndex="PublishTime" Align="Center" >
<Renderer Fn="Ext.util.Format.dateRenderer('Y年m月d日')" />
</ext:Column>
<ext:Column ColumnID="DownloadCount" Header="下载次数" DataIndex="DownloadCount" Align="Center" />
<ext:Column ColumnID="Path" Header="下载" DataIndex="Path" Align="Center" />
</Columns>
</ColumnModel>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server">
</ext:RowSelectionModel>
</SelectionModel>
<View>
<ext:GridView ID="GridView1" runat="server" ForceFit="true" MarkDirty="false" />
</View>
<BottomBar>
<ext:PagingToolbar ID="PagingToolbar1" runat="server" PageSize="30" HideRefresh="true" />
</BottomBar>
<LoadMask ShowMask="true" />
</ext:GridPanel>
三、如果<ext:RecordField Name="PublishTime" Type="String"/>的数据类型是String,而不是Date,同样会产生上述问题,尤其是日期格式为xxxx-xx-xx时,
要将“-”分隔符转换为“/”
<ext:Column ColumnID="PublishTime" Header="发布日期" DataIndex="PublishTime" Align="Center" >
<Renderer Handler="if(value)return Ext.util.Format.date(new Date(value.replace('-','/')),'Y年m月d日');else return value;" /> <%--对空字符串过滤-->
</ext:Column>
日期转换参考:
到此问题解决。