Преобразовать строку первого дня в дату и время - PullRequest
0 голосов
/ 03 сентября 2018

Я ищу способ преобразовать строку с датой так:

"1st Oct 2018" => 2018-10-01

Или это:

"10th Mar 2015" => 2015-03-10

эквивалентно string в формате yyyy mm dd. Я попробовал следующий код, но не повезло:

DateTime dt = DateTime.ParseExact(stringDate, "yyyy mm dd", CultureInfo.InvariantCulture);

Ответы [ 3 ]

0 голосов
/ 03 сентября 2018

Просто в дополнение к отличному ответу от Дейзи:

[TestCase("15th Oct 2018")]
[TestCase("1st Oct 2018")]
[TestCase("2nd Oct 2018")]
[TestCase("3rd Oct 2018")]
[TestCase("3d Oct 2018")]
public void Action(string dateStr)
{
    // Act
    var dt = DateTime.ParseExact(Regex.Replace(dateStr, "(th|st|nd|rd|d)", ""), "d MMM yyyy", CultureInfo.CurrentCulture);

    //Assert
    Console.WriteLine(dt);
}

UPD: добавлены отличные предложения от Дмитрия Быченко.

0 голосов
/ 03 сентября 2018

Существует также нативный подход без удаления / замены / Regex строки

Если вы знаете символы, вы можете избежать их с помощью символа ' внутри шаблона даты. Так что "15th Oct 2018" работает для этого шаблона "d'th' MMM yyyy"

Теперь есть "st","nd","rd","th", поэтому вы можете попробовать каждый из них и выбрать рабочий.

В перегрузку TryParseExact(String, String[], IFormatProvider, DateTimeStyles, DateTime) можно передать диапазон допустимых форматов.

string input = "15th Oct 2018";
DateTime result = DateTime.Now;
string[] patterns = { "d'st' MMM yyyy", "d'nd' MMM yyyy", "d'rd' MMM yyyy", "d'th' MMM yyyy"};
bool success = DateTime.TryParseExact(input, patterns, CultureInfo.InvariantCulture, DateTimeStyles.None, out result);
if (success)
    Console.WriteLine(result.ToString("yyyy-MM-dd"));

https://dotnetfiddle.net/H8ulyo

0 голосов
/ 03 сентября 2018

A DateTime значение не имеет формата - это просто значение. (Точно так же, как int не является по своей сути десятичным или шестнадцатеричным - вы выбираете, как отформатировать его при преобразовании в строку, и по умолчанию используется десятичное число.)

Строка, в которую вы передаете DateTime.ParseExact, является ожидаемым форматом ввода - и ваши строки не имеют формата "гггг мм дд". (Обратите внимание, что в строках формата даты / времени «мм» означает минуты, так что вы все равно захотите «ММ» вместо «мм» ... но здесь это не поможет.)

Ваш формат даты почти"d MMM гггг" (день, короткое название месяца, год) с использованием английских названий месяцев, но проблема заключается в порядковой части ("st", "nd", " го "). Насколько я знаю, нет простого способа справиться с этим с помощью DateTime.ParseExact. Вместо этого я, вероятно, использовал бы регулярное выражение или простую замену строки, чтобы удалить порядковую часть, чтобы у вас do была строка в формате "d MMM yyyy", а затем она была проанализирована.

Для части, заменяющей строку, уместны ответы на этот вопрос . Итак, вот полный пример, использующий ваши примеры данных:

using System;
using System.Globalization;

class Test
{
    static void Main()
    {
        Console.WriteLine(ParseWithOrdinals("10th Mar 2015"));
        Console.WriteLine(ParseWithOrdinals("1st Oct 2018"));
    }

    private static DateTime ParseWithOrdinals(string input) =>
        DateTime.ParseExact(
            RemoveOrdinals(input), // Text to parse
            "d MMM yyyy",          // Format of text
            CultureInfo.InvariantCulture); // Expect English month names, Gregorian calendar


    // From https://stackoverflow.com/questions/17710561
    private static string RemoveOrdinals(string input) =>
        input
            .Replace("0th", "0")
            .Replace("1st", "1")
            .Replace("2nd", "2")
            .Replace("3rd", "3")
            .Replace("11th", "11") // Need to handle these separately...
            .Replace("12th", "12")
            .Replace("13th", "13")
            .Replace("4th", "4")
            .Replace("5th", "5")
            .Replace("6th", "6")
            .Replace("7th", "7")
            .Replace("8th", "8")
            .Replace("9th", "9");
}

(Обратите внимание, что я не форматировал результат как yyyy-MM-dd в выводе, поэтому вы получите локальный формат даты / времени.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...