Как разобрать время, чтобы добавить его к дате? - PullRequest
0 голосов

У меня есть строка в следующем формате: 05/06/2019|1330|60

Вывод, который я ищу: 05/06/2019T14:30:00

Я сейчас пытаюсь разобрать часть TimeSpan:

  public static string getProcedureEndingDateTime (string input) {
    //05/06/2019|1330|60

    string myDate = input.Split ( '|' ) [0];
    DateTime myDateTime = DateTime.Parse (myDate);

    string myTime = input.Split('|')[1];
    string hours = myTime.Substring(0,2);
    string minutes = myTime.Substring(2,2);
    TimeSpan myTimeSpan = TimeSpan.Parse($"{hours}:{minutes}");

    myDateTime.Add(myTimeSpan);

    return myDateTime.ToString();
}

Но сейчас получаем следующий вывод:

enter image description here

Чтобы получить приведенный выше вывод, я вызываю свою функцию так:

Console.WriteLine (getProcedureEndingDateTime("05/06/2019|1330|60"));

Как мне разобрать строку "1330" в интервал времени?

Ответы [ 4 ]

2 голосов
/ 08 мая 2019

Проблема в том, что Add() возвращает новый экземпляр DateTime, что означает, что вы в настоящий момент его отбрасываете. Сохраните его и вместо этого верните его из своей функции, например:

var adjusted = myDateTime.Add(myTimeSpan);
return adjusted.ToString();
2 голосов
/ 08 мая 2019

Здесь нам не нужен интервал времени, просто вместо этого вызовите ParseExact с правильным форматом, чтобы сделать это в одной строке.

var myDateTime = DateTime.ParseExact("05/06/2019|1330|60", "dd/MM/yyyy|HHmm|60", CultureInfo.InvariantCulture);
Console.WriteLine(myDateTime.ToString()); 
//this gives 2019-06-05 1:30:00 PM, format depends on your PC's locale

Я не знаю, что это за 60-я часть, вы можете отрегулировать формат или подставить его заранее.

1 голос
/ 09 мая 2019

Предполагая, что показанная дата - 6 мая (а не 5 июня), а также предполагая, что 60 представляет смещение часового пояса, выраженное в минутах запад по Гринвичу, а также предполагая, что вы хотите соответствующий UTCзатем значение:

public static string getProcedureEndingDateTime (string input) {

    // example input: "05/06/2019|1330|60"

    // separate the offset from the rest of the string
    string dateTimeString = input.Substring(0, 15);
    string offsetString = input.Substring(16);

    // parse the DateTime as given, and parse the offset separately, inverting the sign
    DateTime dt = DateTime.ParseExact(dateTimeString, "MM/dd/yyyy|HHmm", CultureInfo.InvariantCulture);
    TimeSpan offset = TimeSpan.FromMinutes(-int.Parse(offsetString));

    // create a DateTimeOffset from these two components
    DateTimeOffset dto = new DateTimeOffset(dt, offset);

    // Convert to UTC and return a string in the desired format
    DateTime utcDateTime = dto.UtcDateTime;
    return utcDateTime.ToString("MM/dd/yyyy'T'HH:mm:ss", CultureInfo.InvariantCulture);
}

Несколько дополнительных пунктов:

  • Не только странный формат ввода, но и желаемый формат вывода.Странно видеть T, разделяющий дату и время, а также видеть дату в формате 05/06/2019.T почти всегда означает использование ISO 8601 , для которого требуются упорядочивание по годам и дням и разделители дефисов.Я бы предложил либо удалить T, если вы хотите формат, специфичный для локали, либо оставить T и использовать стандартный формат.Не делайте и то, и другое.

  • В ISO 8601 также неплохо добавить Z к значениям на основе UTC.Для значений DateTime для этого следует использовать спецификатор K .Другими словами, вы, вероятно, хотите, чтобы последняя строка выше была:

    return utcDateTime.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
    
    // outputs: "2019-05-06T14:30:00Z"
    
  • Вы можете не форматировать строку здесь, а вместо этого вернуть DateTime или DateTimeOffsetзначение.Обычно лучше создавать строку только во время отображения.

  • Не забывайте, что структура DateTime неизменна.В вашем вопросе вы игнорировали возвращаемое значение метода Add.

1 голос
/ 08 мая 2019

Попробуйте использовать числовые значения в точности как числа.

Кроме того, другой проблемой с вашим кодом является метод DateTime.Add(), который не добавляет эту переменную DateTime.Вместо этого он возвращает новую переменную, которую вы игнорируете.

Попробуйте это:

 public static string getProcedureEndingDateTime (string input) {
    string[] parts = input.Split('|');
    string myDate = parts[0];
    DateTime myDateTime = DateTime.Parse (myDate);

    string myTime = parts[1];
    if (!int.TryParse(myTime.Substring(0,2), out int hours))
        hours = 0;
    if (!int.TryParse(myTime.Substring(2,2), out int minutes))
        minutes = 0;
    TimeSpan myTimeSpan = new TimeSpan(hours, minutes, 0);

    myDateTime += myTimeSpan;

    return myDateTime.ToString();
}
...