Is there a culture-safe way to get ToShortDateString() and ToShortTimeString() with leading zeros?
I know that I could use a format string, but I don't want to lose the culture specific representation of the date/time format. E.g.
5/4/2011 | 2:06 PM | ...
should be 05/04/2011 | 02:06 PM | ...
But when I change it to a different culture, I wa开发者_如何学Pythonnt it to be
04.05.2011 | 14:06 | ...
without changing the format string. Is that possible?
You can use the DateTimeFormatInfo.CurrentInfo
ShortDatePattern
and ShortTimePattern
to do the translation:
// Change the culture to something different
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-AT");
DateTime test_datetime = new DateTime(2008, 10, 2, 3, 22, 12);
string s_date = test_datetime.ToString(DateTimeFormatInfo.CurrentInfo);
// For specifically the short date and time
string s_date1 =
test_datetime.ToString(DateTimeFormatInfo.CurrentInfo.ShortDatePattern);
string s_time1 =
test_datetime.ToString(DateTimeFormatInfo.CurrentInfo.ShortTimePattern);
// Results
// s_date1 == 02.10.2008
// s_time1 == 03:22
I see only a single solution - you should obtain the current culture display format, patch it so that it meets your requirement and finally format your DateTime value using the patched format string. Here is some sample code:
string pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
DateTime dt = DateTime.Now;
string[] format = pattern.Split(new string[] { CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator }, StringSplitOptions.None);
string newPattern = string.Empty;
for(int i = 0; i < format.Length; i++) {
newPattern = newPattern + format[i];
if(format[i].Length == 1)
newPattern += format[i];
if(i != format.Length - 1)
newPattern += CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator;
}
As promised, here is the improved version:
/// <summary>
/// Extensions for the <see cref="DateTime"/> class.
/// </summary>
public static class DateTimeExtensions
{
/// <summary>
/// Provides the same functionality as the ToShortDateString() method, but
/// with leading zeros.
/// <example>
/// ToShortDateString: 5/4/2011 |
/// ToShortDateStringZero: 05/04/2011
/// </example>
/// </summary>
/// <param name="source">Source date.</param>
/// <returns>Culture safe short date string with leading zeros.</returns>
public static string ToShortDateStringZero(this DateTime source)
{
return ToShortStringZero(source,
CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern,
CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator);
}
/// <summary>
/// Provides the same functionality as the ToShortTimeString() method, but
/// with leading zeros.
/// <example>
/// ToShortTimeString: 2:06 PM |
/// ToShortTimeStringZero: 02:06 PM
/// </example>
/// </summary>
/// <param name="source">Source date.</param>
/// <returns>Culture safe short time string with leading zeros.</returns>
public static string ToShortTimeStringZero(this DateTime source)
{
return ToShortStringZero(source,
CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern,
CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator);
}
private static string ToShortStringZero(this DateTime source,
string pattern,
string seperator)
{
var format = pattern.Split(new[] {seperator}, StringSplitOptions.None);
var newPattern = string.Empty;
for (var i = 0; i < format.Length; i++)
{
newPattern = newPattern + format[i];
if (format[i].Length == 1)
newPattern += format[i];
if (i != format.Length - 1)
newPattern += seperator;
}
return source.ToString(newPattern, CultureInfo.InvariantCulture);
}
}
Really complicated answers here. In reality it's as simple as
datetime.ToString("d", culture) // Short date
datetime.ToString("t", culture) // Short time
For a full list of all formats with example outputs see https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tostring?view=net-5.0.
You could also override the CurrentThread.CurrentCulture class. At the beginning of your program you call this method:
private void FixCurrentDateFormat()
{
var cc = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
var df = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat;
df.FullDateTimePattern = PatchPattern(df.FullDateTimePattern);
df.LongDatePattern = PatchPattern(df.LongDatePattern);
df.ShortDatePattern = PatchPattern(df.ShortDatePattern);
//change any other patterns that you could use
//replace the current culture with the patched culture
System.Threading.Thread.CurrentThread.CurrentCulture = cc;
}
private string PatchPattern(string pattern)
{
//modify the pattern to your liking here
//in this example, I'm replacing "d" with "dd" and "M" with "MM"
var newPattern = Regex.Replace(pattern, @"\bd\b", "dd");
newPattern = Regex.Replace(newPattern, @"\bM\b", "MM");
return newPattern;
}
With this, anywhere you display a date as a string in your program it will have the new format.
I wrote a method to do that kind of transformations :
/// <summary>
/// Transform DateTime into short specified format
/// </summary>
/// <param name="strDateTime">string : input DateTime</param>
/// <param name="cultureInfo"></param>
/// <param name="strFormat">string - optional : ouput format - default "d"</param>
/// <returns></returns>
public static string ConvertDateTimeToShortDate(string strDateTime, CultureInfo cultureInfo, string strFormat="d")
{
var dateTime = DateTime.MinValue;
return DateTime.TryParse(strDateTime, out dateTime) ? dateTime.ToString(strFormat, cultureInfo) : strDateTime;
}
To call it, for time format :
DateTimeTools.ConvertDateTimeToShortDate(DateTime.Today.ToString(),
CultureInfo.InvariantCulture,"t");
Hope it can help u
精彩评论