2016-06-06 4 views
0

Я пытаюсь сделать короткую дату, но в результате получаю еще один день. С датой вроде «2014-01-03 00:00:00» ее хорошо, но она терпит неудачу, когда время «23:59:59».C# создание короткой даты заканчивается добавлением одного дня

EntryDate = "2014-01-03 23:59:59"

но получить результат = "2014-01-04"

try 
     { 
      DateTime exact = DateTime.ParseExact(EntryDate, "yyyyMMdd", (IFormatProvider)CultureInfo.InvariantCulture); 
      mventryAttrib.Value = (exact.ToLocalTime().ToString("yyyy-MM-dd")); 
     } 
     catch (FormatException ex) 
     { 
      try 
      { 
       DateTime exact = DateTime.ParseExact(EntryDate, "yyyy-MM-dd HH:mm:ss", (IFormatProvider)CultureInfo.InvariantCulture); 
       mventryAttrib.Value = (exact.ToLocalTime().ToString("yyyy-MM-dd")); 
      } 
      catch 
      { 
      } 
+2

, что о добавлении .Date в конце вызова ParseExact (чтобы удалить компонент времени). Кроме того, будет ли ToLocalTime() не возиться с датой в любом случае в зависимости от часового пояса? – Warrick

+0

Это из-за 'ToLocalTime'. Если вы находитесь в часовом поясе, который добавляет часы, тогда это будет отражать его в 2014-01-04. –

+1

Почему вы переходите в местное время, если вас не волнует время? Это позволит настроить время, которое сделает его на следующий день, когда ваш часовой пояс будет впереди. Если вы просто преобразуете 'exact' в строку, то он даст вам правильную дату. –

ответ

3

Это связано с ParseExact возвращает DateTime с Kind значение свойства DateTimeKind.Unspecified.

Это, в сочетании с вызовом .ToLocalTime(), когда вы находитесь в часовом поясе, который имеет положительное смещение от UTC, будет ударять значение DateTime вперед с тем, что многими часами и возвращает значение DateTime со значением Kind собственности DateTimeKind.Local ,

Вот короткая программа, которая продемонстрирует:

var exact = DateTime.ParseExact("2014-01-03 23:59:59", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); 
Console.WriteLine($"{exact} - {exact.Kind}"); 

var local = exact.ToLocalTime(); 
Console.WriteLine($"{local} - {local.Kind}"); 

Console.WriteLine(TimeZone.CurrentTimeZone.GetUtcOffset(exact)); 

Output (на моей машине):

03.01.2014 23.59.59 - Unspecified 
04.01.2014 00.59.59 - Local 
01:00.00 

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

exact = new DateTime(exact.Ticks, DateTimeKind.Local); 

Помните, что это может иметь непредвиденные последствия при работе с границами часового пояса. Я бы настоятельно рекомендовал вам найти лучшую библиотеку, чем встроенные типы DateTime, такие как Noda Time.

0

Это выглядит так, как будто вы устанавливаете время в точно как время UTC, а затем преобразует его в локальное время. Это преобразование добавляет несколько часов к времени и, следовательно, переносит дату.

Попробуйте точно.ToUniversalTime(), и вы должны установить дату, которую вы установили.