|
最近业务部门总是反馈说查询出来的文档发布日期不对,检查后发现,实际日期和显示的日期总有8H的差值。8这个数字应该就是北京时间和UTC时间的时差了。
翻阅了一些资料(http://www.novolocus.com/2008/07/31/sharepoint-web-services-and-utc-time-fun-and-games/),下面做一些测试。
我们知道Sharepoint是支持多个时区的,用户可以设置自己合适的时区。因此sharepoint采用UTC方式来存储时间,不管哪个时区的时间,最终写入sharepoint的都是UTC时间。
测试环境:Sharepoint 2010
测试数据:以2011年12月22日 12:22:11为例。列表:TestUTC 栏:MyTime(日期和时间)
1.采用webservice方式更新时间字段。注意,此方式要求更新的时间格式为yyyy-MM-ddTHH:mm:ssZ
protected void UpdateByWebService()
{
DateTime dt = DateTime.Parse("2011-12-22 12:22:11");
ListService.Lists lst = new ListService.Lists();
lst.Url = "http://mydemo/_vti_bin/Lists.asmx";
lst.Credentials = CredentialCache.DefaultCredentials;
XmlDocument xml = new XmlDocument();
XmlElement xe = xml.CreateElement("Batch");
xe.SetAttribute("OnError", "Continue");
XmlNode xnResult = null;
string strXml = @"<Method ID='1' Cmd='Update'>
<Field Name='ID'>1</Field>
<Field Name='MyTime'>{0}</Field>
</Method>";
xe.InnerXml = string.Format(strXml, dt.ToString("yyyy-MM-ddTHH:mm:ssZ"));
xnResult = lst.UpdateListItems("TestUTC", xe);
}
2.采用COM方式更新时间字段。
protected void UpdateByCOM()
{
DateTime dt = DateTime.Parse("2011-12-22 12:22:11");
using (SP.ClientContext context = new SP.ClientContext("http://mydemo/"))
{
context.Credentials = CredentialCache.DefaultCredentials;
SP.List lst = context.Web.Lists.GetByTitle("TestUTC");
context.Load(lst);
SP.ListItem li = lst.GetItemById(2);
context.Load(li);
if (li == null) return;
li["MyTime"] = dt.ToString("yyyy-MM-ddTHH:mm:ssZ");//dt.ToString();
li.Update();
context.ExecuteQuery();
}
}
3.通过webservice方式读取时间字段。
protected void ReadFromWebservice()
{
ListService.Lists lst = new ListService.Lists();
lst.Url = "http://mydemo/_vti_bin/Lists.asmx";
lst.Credentials = CredentialCache.DefaultCredentials;
XmlDocument xmlDoc = new XmlDocument();
XmlNode xnQuery = xmlDoc.CreateElement("Query");
string xmlFilter = @"<Where><Eq><FieldRef Name='ID' /><Value Type='Text'>1</Value></Eq></Where>";
xnQuery.InnerXml = xmlFilter;
XmlNode xnList = lst.GetListItems("TestUTC", "{4208DB7A-A0E1-4699-9187-A15AB78234B5}", xnQuery, null, "1", null, null);
int itemCount = Convert.ToInt16(xnList.ChildNodes[1].Attributes["ItemCount"].Value);
if (itemCount < 1) return;
string strMyTime = string.Empty;
foreach (XmlNode xn in xnList.ChildNodes[1].ChildNodes)
{
if (xn.Name.ToLower() != "z:row") continue;
strMyTime = xn.Attributes["ows_MyTime"].Value;
}
lblWB.Text = strMyTime;
}
4.通过COM读取时间字段。
protected void ReadFromCOM()
{
string strMyTime = string.Empty;
using (SP.ClientContext context = new SP.ClientContext("http://mydemo/"))
{
context.Credentials = CredentialCache.DefaultCredentials;
SP.List lst = context.Web.Lists.GetByTitle("TestUTC");
context.Load(lst);
SP.ListItem li = lst.GetItemById(1);
context.Load(li);
context.ExecuteQuery();
if (li == null) return;
strMyTime = ((DateTime)li["MyTime"]).ToString();
}
lblCOM.Text = strMyTime;
}
5.结果对比
时区:东八区,时差+8H,即北京时间=UTC+8H | 传入参数值 | Client Object Model更新 | Webservice更新 | 界面显示 | 通过webservice读取 | 通过COM读取 | 界面显示 | 通过webservice读取 | 通过COM读取 | 2011-12-22T12:22:00Z | 2011/12/23 4:22
| 2011/12/23 4:22 | 2011/12/22 20:22 | 2011/12/22 12:22 | 2011/12/22 12:22 | 2011/12/22 4:22 | 2011/12/22 12:22 | 2011/12/22 20:22 | 2011/12/22 20:22 | 2011/12/22 12:22 | NULL | NULL | NULL | 2011-12-22T4:22:00Z | 2011/12/22 20:22 | 2011/12/22 20:22 | 2011/12/22 12:22 | 2011/12/22 4:22 | 2011/12/22 4:22 | 2011/12/21 12:22 | 2011/12/22 4:22 | 2011/12/22 12:22 | 2011/12/22 12:22 | 2011/12/22 4:22 | NULL | NULL | NULL | 从表格中看出
- 通过webservice更新时间字段时,已经要求了时间格式,并且该时间值会作为UTC时间写入到sharepoint中。在这种情况下通过COM读取该时间字段,会进行-8H的处理。可以认为通过COM方式读取时间字段时候,sharepoint默认会根据UTC时间和用户时区进行时间转换。
- 通过COM更新时间字段时,若传入的参数值已经按格式yyyy-MM-ddTHH:mm:ssZ(UTC)格式化,sharepoint在接受该参数时,a)先转换为时区时间(+8). b)最后在写入sharepoint时,会根据本地时区和UTC的时差进行转换(--8,因为读取的时是-8)。若传入的参数值未进行UTC格式化,则跳过a步骤,之后的读取结果也是一样。
- 总之,通过webservice写入的时间值直接作为UTC时间,期间不会进行时区转换。通过COM方式写入时,根据参数值的格式,时区转换差额存在区别。
|
|
|