无法将这种格式的字符串“ 1/29/2020 12:00:00 AM”解析为有效的DateTime

时间:2020-02-24 13:57:18

标签: c# sharepoint csom

我正在使用SVC服务,当我在本地运行它时,我得到Date字段,其内容为30/01/2020 00:00:00,然后将其解析为DateTime,如下(DateTime.ParseExact(i["ProjectLastUpdate"].ToString(), "dd/MM/yyyy hh:mm:ss", CultureInfo.InvariantCulture).ToString("yyyy'-'MM'-'dd'T'00':'00':'00'Z'")),由于我的本地计算机使用的是英国区域设置。但是,当我在Azure Web App中托管服务时,我开始收到如下日期字符串:1/29/2020 12:00:00 AM,并且该服务将在上面的代码中引发此异常“String was not recognized as a valid DateTime”。那么任何人都可以对此提出建议吗?我可以在本地计算机和Azure上标准化日期格式吗?还可以强制我的代码在两种环境下都能工作吗?

这是我在服务中的完整代码:-

using (ClientContext context = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
{
    CamlQuery camlQuery = new CamlQuery();
    camlQuery.ViewXml = string.Format("<View Scope=\"RecursiveAll\"><Query><Where><Eq><FieldRef Name='ID' /><Value Type='Number'>{0}</Value></Eq></Where></Query></View>", listItemID);
    ListItemCollection collListItem = context.Web.Lists.GetByTitle("Project Update System").GetItems(camlQuery);
    context.Load(collListItem);
    foreach (ListItem i in collListItem)
    {
        var mydate = (DateTime.ParseExact(i["ProjectLastUpdate"].ToString(), "dd/MM/yyyy hh:mm:ss", CultureInfo.InvariantCulture).ToString("yyyy'-'MM'-'dd'T'00':'00':'00'Z'"));

2 个答案:

答案 0 :(得分:2)

i["ProjectLastUpdate"]的值已经 DateTime,因此无需将其转换为字符串然后再解析回去。因此,您可以使用简单的类型转换:

var mydate = (DateTime) i["ProjectLastUpdate"].

答案 1 :(得分:1)

这个问题已经被问过3次了,每个问题都有不同的细节。让我们放在一起:

  • 数据使用CAML查询来自SharePoint。
  • ProjectLastUpdate已经是一个DateTime。 (来自评论here
  • real 问题是如何将此DateTime与UTC的ISO8601格式的字符串(即YYYY-MM-DD-THH:mm:ssZ)进行比较。
  • 或者是,如何使用UTC日期进行过滤?在CAML中,可以通过向过滤器值添加StorageTZ='TRUE'属性来完成此操作。

日期比较

答案是将比较字符串转换为DateTime,而不是将DateTime转换为字符串。完成此操作后,我们就可以使用otherDate.Equals(spDate)otherDate.CompareTo(spDate)

SharePoint值已经是一个装在对象中的DateTime。 DateTime.EqualsDateTime.CompareTo具有可与装箱日期时间一起使用的重载,因此我们甚至不需要强制转换为DateTime

我们可以使用:

var myDate = (DateTime) i["ProjectLastUpdate"];

或者只是

var mydate = i["ProjectLastUpdate"];

起什么作用,正在解析比较值。这里的事情变得有趣。

DateTime.Parse(string)本身可以毫无问题地解析此字符串。但是它将返回一个 local 时间。在我的时区,格林尼治标准时间+2:00,此代码:

var otherDate=DateTime.Parse("2020-02-25T00:00:00Z");

返回DateTime对象,其KindLocal,值是2020-02-25T02:00:00

SharePoint仍存储UTC日期时间。为此,我们需要DateTime.Parse overload接受一个DateTimeStyles参数。这段代码:

var otherDate=DateTime.Parse("2020-02-25T00:00:00Z",null, DateTimeStyles.RoundtripKind);

这将返回DateTime,其Kind为UTC,值为2020-02-25T00:00:00

使用UTC进行CAML过滤

问题CAML query compare DateTime in UTC询问如何在UTC中进行查询。默认情况下,SharePoint将存储的UTC转换为本地时间,并且满足以下条件:

<Gt>
    <FieldRef Name='ProjectLastUpdate ' />
    <Value IncludeTimeValue='TRUE' Type='DateTime'>2018-06-28T00:00:00Z</Value>
</Gt>

将在当地时间工作。要使用UTC进行比较,我们需要添加StorageTZ='TRUE

<Gt>
    <FieldRef Name='ProjectLastUpdate ' />
    <Value IncludeTimeValue='TRUE' `StorageTZ='TRUE` Type='DateTime'>2018-06-28T00:00:00Z</Value>
</Gt>

另一方面,如果我们只关心日期,则可以简单地忽略时间值:

<Gt>
    <FieldRef Name='ProjectLastUpdate ' />
    <Value IncludeTimeValue='FALSE' `StorageTZ='TRUE` Type='DateTime'>2018-06-28T00:00:00Z</Value>
</Gt>