[英]Get Day And Month portion of culture specific date
当使用 CultureInfo.CurrentCulture.DateTimeFormat 获取本地日期格式时,是否有内置的方法来获取本地 ShortTimePattern 返回的日期的日和月部分? 例如日/月
基本上,在我的剃刀看来,我正在做这样的事情:
@someObject.Date.ToString("dd/MM")
但是现在需要让它与当前文化一起工作,所以我希望找到一种方法来提供基于当前文化的动态格式掩码。 想象一下:
@someObject.Date.ToString(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePatternNoYear)
为每种文化设置月和日模式是个坏消息。 在这种情况下, DRY 原则说要利用每个文化的日期时间格式,而不是用自定义的MonthDayPattern
重复(并且可能矛盾)它。
而是利用短日期 ("d") 格式说明符以正确的顺序获取月份和日期,并为相关文化正确分隔,然后重击年份(及其分隔符)。
var de = CultureInfo.CreateSpecificCulture("de-DE").DateTimeFormat;
var uk = CultureInfo.CreateSpecificCulture("en-GB").DateTimeFormat;
var us = CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat;
var now = DateTime.Now;
var yearNow = now.Year.ToString(CultureInfo.InvariantCulture);
const string yearPattern = "(^{0}{1}|{1}{0}$)"; // {0} = year, {1} = date separator
var deDate = now.ToString("d", de);
var deYearlessDate =
Regex.Replace(
deDate,
String.Format(yearPattern, yearNow, de.DateSeparator),
"");
// or a double String.Replace instead of a Regex.Replace
//var deYearlessDate =
// deDate.Replace(de.DateSeparator + yearNow, "").Replace(yearNow + de.DateSeparator, "");
var ukDate = now.ToString("d", uk);
var ukYearlessDate =
Regex.Replace(
ukDate,
String.Format(yearPattern, yearNow, uk.DateSeparator),
"");
// or a double String.Replace instead of a Regex.Replace
//var ukYearlessDate =
// ukDate.Replace(uk.DateSeparator + yearNow, "").Replace(yearNow + uk.DateSeparator, "");
var usDate = now.ToString("d", us);
var usYearlessDate =
Regex.Replace(
usDate,
String.Format(yearPattern, yearNow, us.DateSeparator),
"");
// or a double String.Replace instead of a Regex.Replace
//var usYearlessDate =
// usDate.Replace(us.DateSeparator + nowYear, "").Replace(nowYear + us.DateSeparator, "");
Console.WriteLine(deYearlessDate); // 02.04
Console.WriteLine(ukYearlessDate); // 02/04
Console.WriteLine(usYearlessDate); // 4/2
解决方案是找到您当前的文化并更新 DateTimeFormat.MonthDayPattern。
.NET 中的自定义文化感知日期格式表示 ShortDatePattern ("d") 不可靠并建议使用以下方法:
private static string FindMonthDayOnly(System.Globalization.CultureInfo ci)
{
string shortPattern = ci.DateTimeFormat.ShortDatePattern;
while(shortPattern[0] != 'd' && shortPattern[0] != 'M')
{
shortPattern = shortPattern.Substring(1);
if(shortPattern.Length == 0)
return ci.DateTimeFormat.ShortDatePattern;
}
while(shortPattern[shortPattern.Length - 1] != 'd' && shortPattern[shortPattern.Length - 1] != 'M')
{
shortPattern = shortPattern.Substring(0, shortPattern.Length - 1);
if(shortPattern.Length == 0)
return ci.DateTimeFormat.ShortDatePattern;
}
return shortPattern;
}
然后你所要做的就是找到一个方便的地方来运行这样的东西(仔细考虑后台线程等,因为它只适用于当前线程):
var culture = new CultureInfo(CultureInfo.CurrentCulture.IetfLanguageTag);
var newMonthDayString = FindMonthDayOnly(culture);
culture.DateTimeFormat.MonthDayPattern = newMonthDayString;
Thread.CurrentThread.CurrentCulture = culture;
感谢大家的投入。 这似乎有效,但如果您发现解决方案有任何明显问题,请发表评论。
您可以自己更改MonthDayPattern
。 有点像这样:
var uk = CultureInfo.CreateSpecificCulture("en-GB").DateTimeFormat;
uk.MonthDayPattern = "dd/MM";
var us = CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat;
us.MonthDayPattern = "MM/dd";
Console.WriteLine(DateTime.Now.ToString("m", uk)); // 03/04
Console.WriteLine(DateTime.Now.ToString("m", us)); // 04/03
默认情况下,英国的输出为3 April
,美国的输出为April 3
。 通过更改MonthDayPattern
您可以将其自定义为数字。
我创建了一个扩展方法来根据 CultureInfo 仅显示月和日,希望它有所帮助:
/// <summary>
/// Return a date formatted MonthDay depending of the current application cutlure
/// </summary>
/// <param name="datetime">The datetime to parse</param>
/// <returns>A Month day string representation</returns>
public static string ToMonthDay(this DateTime datetime)
{
// Get the current culture of the application
var culture = new CultureInfo(Thread.CurrentThread.CurrentCulture.Name);
// Get the format depending of the culture of the application
var output = culture.DateTimeFormat.ShortDatePattern;
// Remove the Year from from the date format
var format = output.Replace("Y", "").Replace("y", "");
// Remove any character before or after in the text string which is not a number
Regex rgx = new Regex("^[^a-zA-Z0-9]|[^a-zA-Z0-9]$");
format = rgx.Replace(format, "");
return datetime.ToString(format);
}
以及用法:
DateTime dateToDisplay = new DateTime(2009, 01, 31);
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
Console.WriteLine(dateToDisplay.ToMonthDay());
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Console.WriteLine(dateToDisplay.ToMonthDay());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.