Ответ 1
Получение разделителей
Как заявил Jeppe Stig Nielson (возможно, для него выше), нет хорошего способа получить второй таймер или разделитель даты, потому что в строке формата, например
HH-mm/HH:mm-HH/mm
их может быть несколько, даже с той же семантикой (например, между часами и минутами).
Отчет об ошибке Microsoft
Я зарегистрировался в Microsoft Connect и зарегистрировал ошибку как DateTime.ToString( "T" ) и DateTime.ToString( "G" ), Если у вас есть учетная запись Microsoft Connect, вы можете проголосовать, можете ли вы воспроизвести ошибку.
SSCCE для воспроизведения ошибки
using System;
using System.Globalization;
namespace DateTimeToString
{
class Program
{
// Tested on
// Microsoft Windows 7 Enterprise x64 Version 6.1.7601 Service Pack 1 Build 7601
// I should have all official updates installed at the time of writing (2014-03-11)
//
// Microsoft Visual Studio Premium 2012 Version 11.0.61030.00 Update 4
// Microsoft .NET Framework Version 4.5.50938
//
// Type: Console application x86
// Target framework: .NET 4 Client Profile
static void Main()
{
if (DateTimeFormatInfo.CurrentInfo.LongTimePattern != "HH-mm:ss" ||
DateTimeFormatInfo.CurrentInfo.ShortDatePattern != "dd.MM/yyyy")
{
Console.WriteLine("Configure long time format to MM-mm:ss to reproduce the time bug.");
Console.WriteLine("Configure short date format to dd.MM/yyyy to reproduce the date bug.");
Console.WriteLine("Control Panel/Region and Language/Additional settings");
return;
}
var dateTime = DateTime.Now;
Console.WriteLine("Expected: " + dateTime.ToString("HH'-'mm':'ss"));
Console.WriteLine("Actual : " + dateTime.ToString("T"));
Console.WriteLine();
Console.WriteLine("Expected: " + dateTime.ToString("dd'.'MM'/'yyyy HH'-'mm':'ss"));
Console.WriteLine("Actual : " + dateTime.ToString("G"));
Console.WriteLine();
Console.WriteLine("Expected: " + dateTime.ToString("HH'-'mm':'ss"));
Console.WriteLine("Actual : " + dateTime.ToLongTimeString());
Console.WriteLine();
Console.WriteLine("Expected: " + dateTime.ToString("dd'.'MM'/'yyyy"));
Console.WriteLine("Actual : " + dateTime.ToShortDateString());
Console.ReadLine();
}
}
}
Обход
В качестве обходного пути мы можем использовать собственные методы GetTimeFormat и GetDateFormat.
static class Program
{
static void Main()
{
var systemTime = new SystemTime(DateTime.Now);
Console.WriteLine("ShortDatePattern (as reported by .NET): " + DateTimeFormatInfo.CurrentInfo.ShortDatePattern);
var sbDate = new StringBuilder();
GetDateFormat(0, 0, ref systemTime, null, sbDate, sbDate.Capacity);
Console.WriteLine("Date string (as reported by kernel32) : " + sbDate);
Console.WriteLine();
Console.WriteLine("LongTimePattern (as reported by .NET) : " + DateTimeFormatInfo.CurrentInfo.LongTimePattern);
var sbTime = new StringBuilder();
GetTimeFormat(0, 0, ref systemTime, null, sbTime, sbTime.Capacity);
Console.WriteLine("Time string (as reported by kernel32) : " + sbTime);
Console.ReadKey();
}
[DllImport("kernel32.dll")]
private static extern int GetDateFormat(int locale, uint dwFlags, ref SystemTime sysTime,
string lpFormat, StringBuilder lpDateStr, int cchDate);
[DllImport("kernel32.dll")]
private static extern int GetTimeFormat(uint locale, uint dwFlags, ref SystemTime time,
string format, StringBuilder sb, int sbSize);
[StructLayout(LayoutKind.Sequential)]
private struct SystemTime
{
[MarshalAs(UnmanagedType.U2)] private readonly ushort Year;
[MarshalAs(UnmanagedType.U2)] private readonly ushort Month;
[MarshalAs(UnmanagedType.U2)] private readonly ushort DayOfWeek;
[MarshalAs(UnmanagedType.U2)] private readonly ushort Day;
[MarshalAs(UnmanagedType.U2)] private readonly ushort Hour;
[MarshalAs(UnmanagedType.U2)] private readonly ushort Minute;
[MarshalAs(UnmanagedType.U2)] private readonly ushort Second;
[MarshalAs(UnmanagedType.U2)] private readonly ushort Milliseconds;
public SystemTime(DateTime dateTime)
{
Year = (ushort) dateTime.Year;
Month = (ushort) dateTime.Month;
DayOfWeek = (ushort) dateTime.DayOfWeek;
Day = (ushort) dateTime.Day;
Hour = (ushort) dateTime.Hour;
Minute = (ushort) dateTime.Minute;
Second = (ushort) dateTime.Second;
Milliseconds = (ushort) dateTime.Millisecond;
}
}
}