невозможно проанализировать строку этого формата "29.01.2020 12:00:00 AM" в допустимый DateTime - PullRequest
0 голосов
/ 24 февраля 2020

Я работаю над сервисом SV C, и когда я запускаю его локально, я получаю поле 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, я начинаю получать строку даты следующим образом: 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 ]

2 голосов
/ 24 февраля 2020

Значение i["ProjectLastUpdate"] уже равно a DateTime, поэтому нет необходимости преобразовывать его в строку, а затем анализировать ее обратно. Таким образом, вы можете использовать простой тип:

var mydate = (DateTime) i["ProjectLastUpdate"].
1 голос
/ 25 февраля 2020

Этот вопрос уже задавался 3 раза, с разными деталями в каждом вопросе. Давайте соединим все вместе:

  • Данные поступают из SharePoint с использованием CAML-запроса.
  • ProjectLastUpdate уже является датой TimeTime. (из комментариев здесь )
  • Вопрос real состоит в том, как сравнить этот DateTime со строкой в ​​формате ISO8601 в UT C, ie YYYY-MM-DD-THH:mm:ssZ.
  • Или как фильтровать с использованием даты UT C? Это можно сделать в CAML, добавив атрибут StorageTZ='TRUE' к значению фильтра.

Сравнение даты

Ответ - преобразовать строку сравнения DateTime, а не DateTime в строку. Как только это будет сделано, мы можем просто использовать otherDate.Equals(spDate) или otherDate.CompareTo(spDate).

Значением SharePoint уже является DateTime, заключенное в объект. DateTime.Equals и DateTime.CompareTo имеют перегрузки, которые работают с упакованным Datetime, поэтому нам даже не нужно приводить к DateTime.

Мы можем использовать:

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

или просто

var mydate = i["ProjectLastUpdate"];

Что имеет значение , это анализ значения сравнения. Вещи становятся интересными здесь.

DateTime.Parse (string) сама может без проблем проанализировать эту строку. Он вернет время по местному . В моем часовом поясе GMT ​​+ 2: 00 этот код:

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

Возвращает объект DateTime, для которого Kind равно Local и значение 2020-02-25T02:00:00.

UT, сохраненное в SharePoint C datetime, хотя. Чтобы получить это, нам нужна перегрузка DateTime.Parse , которая принимает параметр DateTimeStyles. Этот код:

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

Возвращает DateTime, типом которого является UT C и значением 2020-02-25T00:00:00.

CAML-фильтрация с использованием UT C

Вопрос CAML-запрос сравнения DateTime в UT C спрашивает, как сделать запрос в UT C. По умолчанию SharePoint преобразует сохраненное UT C в местное время, и это условие:

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

будет работать по местному времени. Для сравнения, используя UT C, нам нужно добавить StorageTZ='TRUE:

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

С другой стороны, если мы заботимся только о date , мы можем просто игнорировать время значение:

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