Как проанализировать значение времени "400" (эквивалентно 4:00), используя DateTime.TryParseExact - PullRequest
2 голосов
/ 09 сентября 2010

Я пытаюсь преобразовать введенное пользователем время в TimeSpans.Поскольку у TimeSpan нет метода TryParseExact, я использую метод в DateTime и преобразую выходные данные из него.

Форматы, которые я хочу обработать: 04:00, 0400, 4:00 и 400. Первые три не являются проблемой и соответствуют первым трем случаям в структуре if / else вметод ниже.Четвертый может соответствовать любому из двух последних, но ни один из них не работает.

    private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
    {
        CultureInfo enUS = new CultureInfo("en-US");
        DateTime parsedDate = new DateTime();

        string userInput = (string)e.Value;
        if (DateTime.TryParseExact(userInput, "HH:mm", enUS, DateTimeStyles.None, out parsedDate))
        {
            e.Value = parsedDate.TimeOfDay;
            e.ParsingApplied = true;
        }
        else if (DateTime.TryParseExact(userInput, "HHmm", enUS, DateTimeStyles.None, out parsedDate))
        {
            e.Value = parsedDate.TimeOfDay;
            e.ParsingApplied = true;                
        }
        else if (DateTime.TryParseExact(userInput, "H:mm", enUS, DateTimeStyles.None, out parsedDate))
        {
            e.Value = parsedDate.TimeOfDay;
            e.ParsingApplied = true;
        }
        else if (DateTime.TryParseExact(userInput, "hmm", enUS, DateTimeStyles.None, out parsedDate))
        {
            e.Value = parsedDate.TimeOfDay;
            e.ParsingApplied = true;
        }
        else if (DateTime.TryParseExact(userInput, "Hmm", enUS, DateTimeStyles.None, out parsedDate))
        {
            e.Value = parsedDate.TimeOfDay;
            e.ParsingApplied = true;
        }

    }

Ответы [ 5 ]

4 голосов
/ 09 сентября 2010

Я бы просто сделал string.PadLeft(int totalWidth, char paddingChar) для пользовательского ввода, чтобы убедиться, что длина строки составляет 4 символа (минимум).В результате ваш ввод Hmm будет соответствовать формату HHmm.

userInput = userInput.PadLeft(4, '0'); // "400" becomes "0400"

Если ваша строка уже соответствует или превышает 4, она останется неизменной.

1 голос
/ 09 сентября 2010

Вы можете использовать эту перегрузку DateTime.TryParseExact , чтобы указать несколько форматов за один раз.Не похоже, что формат Hmm будет работать, но вместо этого вы можете использовать целочисленный разбор вот так:

internal static class Program
{
    private static void Main(string[] args)
    {
        Console.WriteLine(ParseTime("04:00"));
        Console.WriteLine(ParseTime("0400"));
        Console.WriteLine(ParseTime("4:00"));
        Console.WriteLine(ParseTime("400"));
    }

    public static TimeSpan ParseTime(string input)
    {
        CultureInfo cultureInfo = new CultureInfo("en-US");
        DateTime parsedDateTime;

        if (!DateTime.TryParseExact(input, new [] { "HH:mm", "HHmm", "H:mm" }, cultureInfo, DateTimeStyles.None, out parsedDateTime))
        {
            int parsedInt32;

            if (!int.TryParse(input, NumberStyles.None, cultureInfo,  out parsedInt32))
            {
                throw new ArgumentException("Unable to parse input value as time in any of the accepted formats.", "input");
            }

            int remainder;
            int quotient = Math.DivRem(parsedInt32, 100, out remainder);

            return new TimeSpan(quotient, remainder, 0);
        }

        return parsedDateTime.TimeOfDay;
    }
}
1 голос
/ 09 сентября 2010

просто общий комментарий - вы можете иметь логическую переменную (например, isValidDate), инициализированную в false и установить в true, где у вас есть

 e.Value = parsedDate.TimeOfDay;
 e.ParsingApplied = true;

, затем переместить этот код в блок if в конце

if isValidDate then
        {
            e.Value = parsedDate.TimeOfDay;
            e.ParsingApplied = true;
        }
0 голосов
/ 05 февраля 2016

Я решил это следующим образом:

DateTime.TryParseExact(
    userInput,
    new[] { "%H", "Hm", "H:m" },
    CultureInfo.InvariantCulture,
    DateTimeStyles.None,
    out parsedDate);

Я должен отдать должное за помощь, которую я получил: Почему TryParseExact не работает на Hmm и Hmmss?

0 голосов
/ 10 апреля 2014

Я использовал опцию регулярных выражений (обычно я знаю, что нужно использовать хуже, но система, которую я использовал, требовала этого ... не спрашивайте):

Regex.Replace("935", "^([0-9]{3})$", "0$1"); // outputs "0935"
...