我正在寻找一种能够像这样转换日期字符串的方法:
"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);
除了Daisy的精彩回答:
[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:Dmitry Bychenko提出了很好的建议。
DateTime
值没有格式 - 它只是一个值。 (就像int
本身不是十进制或十六进制 - 当你将它转换为字符串时,你选择如何格式化它,默认是使用十进制。)
您传入DateTime.ParseExact
的字符串是预期的输入格式 - 您的字符串不具有格式“yyyy mm dd”。 (请注意,在日期/时间格式字符串中,“mm”表示分钟,因此您仍然需要“MM”而不是“mm”......但这在这里无济于事。)
您的日期格式几乎是“d MMM yyyy”(白天,短月份名称,年份),使用英文月份名称 - 但问题是序数部分(“st”,“nd”,“th”)。据我所知,没有简单的方法来处理DateTime.ParseExact
。相反,我可能会使用正则表达式或简单的字符串替换来删除序数部分,因此您确实拥有格式为“d MMM yyyy”的字符串,然后解析它。
对于字符串替换部分,this question的答案是合适的。这是使用您的示例数据的完整示例:
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,因此您将获得本地日期/时间格式。)
还有一种没有字符串删除/替换/正则表达式的本机方法
如果您知道这些字符,则可以使用日期模式中的'
字符来转义它们。所以"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"));