使用CultureInfo.CurrentCulture.DateTimeFormat获取本地日期格式时,是否有内置方法只获取本地ShortTimePattern返回的日期的日期和月份部分?例如DD / MM
基本上,在我的剃刀视图中,我正在做这样的事情:
@someObject.Date.ToString("dd/MM")
但是现在需要让它与当前文化一起工作,所以我希望找到一种方法来提供基于当前文化的动态格式掩码。想象一下:
@someObject.Date.ToString(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePatternNoYear)
答案 0 :(得分:2)
设置每种文化的月和日模式是个坏消息。在这种情况下,DRY principle表示要利用每种文化的日期时间格式,而不是使用自定义MonthDayPattern
重复(并可能与之相矛盾)。
相反,利用Short Date ("d") format specifier以正确的顺序获取月份和日期,并针对相关文化进行适当分隔,然后敲打年份(及其分隔符)。
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
答案 1 :(得分:1)
解决方案是找到您当前的文化并更新DateTimeFormat.MonthDayPattern。
Custom culture aware date format in .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;
感谢大家的投入。这似乎有效,但如果您发现解决方案有任何明显问题,请发表评论。
答案 2 :(得分:0)
您可以自己更改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
,您可以将其自定义为数字。
答案 3 :(得分:0)
我创建了一个Extension方法,仅根据文化信息显示月份和日期,希望对您有所帮助:
/// <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());