unable to parse a string of this format “1/29/2020 12:00:00 AM” into a valid DateTime

ぃ、小莉子 提交于 2020-03-30 18:00:12

问题


I am working on a SVC service, and when I run it locally I get the Date field as follow 30/01/2020 00:00:00 and I parse this string to be a DateTime as follow (DateTime.ParseExact(i["ProjectLastUpdate"].ToString(), "dd/MM/yyyy hh:mm:ss", CultureInfo.InvariantCulture).ToString("yyyy'-'MM'-'dd'T'00':'00':'00'Z'")), since my local machine uses the United Kingdom regional setting. But when I host the service inside an Azure Web App, I start receiving the date string as follows: 1/29/2020 12:00:00 AM, and the service will raise this exception “String was not recognized as a valid DateTime” on the above code. So can anyone advice on this please? Can I standardize the date format on both local machine and azure? Also can I force my code to work on both environments?

Here is my full code, inside the service:-

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'"));

回答1:


The value of i["ProjectLastUpdate"] already is a DateTime, so there's no need to convert it to a string and then parse it back. So you can use a simple typecast:

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



回答2:


This question has been asked 3 times already, with different details in each question. Let's put it all together :

  • The data comes from SharePoint, using a CAML query.
  • The ProjectLastUpdate is already a DateTime. (from comments here)
  • The real question is how to compare this DateTime to a string in the ISO8601 format in UTC, ie YYYY-MM-DD-THH:mm:ssZ.
  • Or is it, how to filter using a UTC date? This can be done in CAML, by adding the StorageTZ='TRUE' attribute to the filter value.

Date Comparison

The answer is to convert the comparison string to DateTime, not the DateTime to a string. Once this is done, we can just use otherDate.Equals(spDate) or otherDate.CompareTo(spDate).

The SharePoint value is already a DateTime, boxed in an object. DateTime.Equals and DateTime.CompareTo have overloads that work with a boxed Datetime, so we don't even need to cast to DateTime.

We can use :

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

or just

var mydate = i["ProjectLastUpdate"];

What does matter, is parsing the comparison value. Things get interesting here.

DateTime.Parse(string) by itself can parse this string without trouble. It will return a local time though. In my timezone, GMT+2:00, this code :

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

Returns a DateTime object whose Kind is Local and value 2020-02-25T02:00:00.

SharePoint stored UTC datetime though. To get that, we need the DateTime.Parse overload that accepts a DateTimeStyles parameter. This code :

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

This returns a DateTime whose Kind is UTC and value 2020-02-25T00:00:00.

CAML Filtering using UTC

The question CAML query compare DateTime in UTC asks how to query in UTC. By default, SharePoint converts the stored UTC to local time and this condition :

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

Would work on local time. To compare using UTC, we need to add StorageTZ='TRUE :

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

On the other hand, if we only care about the date, we can simply ignore the time value :

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


来源:https://stackoverflow.com/questions/60377439/unable-to-parse-a-string-of-this-format-1-29-2020-120000-am-into-a-valid-dat

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!