DateTime.ToString("T")和DateTime.ToString("G")中的错误?

Tho*_*ler 20 .net c# datetime

Microsoft指定 :The time separator,但似乎至少有两个时间分隔符:一个在小时和分钟之间,另一个在分钟和秒之间.

控制面板中的长时间格式设置http://uploads.wellisolutions.de/stackoverflow/ControlPanelLongTimeFormat.png

Windows时钟显示的长时间格式http://uploads.wellisolutions.de/stackoverflow/ClockCustomFormat.png

有没有办法获得特定的时间分隔符?我需要几小时和几分钟之间的一个,而几分钟和几秒之间的另一个.

我也不介意以其他方式构建我的DateTime字符串,例如使用标准格式字符串 TG,但它们都不起作用

mydate.ToString("T");
// Output: 20-29-46
// Expected output: 20-29:46 (as shown by Windows clock)

mydate.ToString("G");
// Output: 09/03-2014 20-29-46
// Expected output: 09/03-2014 20-29:46
Run Code Online (Sandbox Code Playgroud)

Tho*_*ler 2

获取分隔符

正如 Jeppe Stig Nielson 所说(也许为他投票),没有好的方法来获取第二个时间或日期分隔符,因为在像这样的格式字符串中

HH-mm/HH:mm-HH/mm
Run Code Online (Sandbox Code Playgroud)

即使具有相同的语义(例如,在小时和分钟之间),也可以有多个。

微软错误报告

我已在 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

解决方法

作为解决方法,我们可以使用本机方法GetTimeFormatGetDateFormat

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)