Microsoft specifies :
为The time separator
,但似乎至少有两个时间分隔符:一个在小时和分钟之间,另一个在分钟和秒之间。
有没有办法获得特定的时间分隔符?我需要几小时和几分钟之间的那一个,而在几分钟和几秒之间需要另一个。
我也不介意用其他方式构建我的DateTime字符串,例如使用standard format string T
或G
,但它们都不起作用
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
答案 0 :(得分:4)
只需根据需要在.NET中设置格式即可。例如:
var clonedProvider = (CultureInfo)CultureInfo.CurrentCulture.Clone();
clonedProvider.DateTimeFormat.LongTimePattern = "HH-mm':'ss";
clonedProvider.DateTimeFormat.ShortDatePattern = "dd'/'MM-yyyy";
然后:
mydate.ToString("T", clonedProvider);
mydate.ToString("G", clonedProvider);
请注意,我将冒号:
和斜杠/
放入单引号(撇号'
)中,以防止它们从一开始就被转换为文化所具有的任何分隔符。我只想要字面冒号和斜线。
如果您不想在任何地方写clonedProvider
,请在当前线程上永久更改文化:
Thread.CurrentThread.CurrentCulture = CultureInfo.ReadOnly(clonedProvider);
你的应用程序中有很多线程吗?
编辑:
如果您想了解操作系统设置如何影响您的.NET格式提供程序对象,只需检查字符串:
DateTimeFormatInfo.CurrentInfo.ShortDatePattern
DateTimeFormatInfo.CurrentInfo.LongTimePattern
等等。我想您当前的格式提供程序已将UseUserOverride
设置为true
,因此Windows中的用户设置将可见。
用户可以输入的“分隔符”数量没有限制。例如,有人可能会使用"ddd;dd-MM,yyyy"
。所以那里有三个分隔符。因此,您必须自己检查字符串,以查看有多少“分隔符”和“组件”,以及用户在每个位置使用哪些字符作为分隔符。
仔细阅读您的问题,并与您的示例相关,我看到您在Windows设置中键入了HH-mm:ss
。这有问题。转换为.NET语法时,第一个分隔符-
变为 时间分隔符。然后.NET中的下一个分隔符冒号是“通配符”,意思是“用时间分隔符替换”。因此冒号也被翻译成破折号。
您应该在Windows设置中键入
HH-mm':'ss
再次使用单引号(撇号)保护冒号。
现在,如果您的某个用户首先使用非标准分隔符,然后使用标准分隔符:
(或/
),而不在单引号中引用后者,该怎么办?那么,在这种情况下你是对的,Windows中的行为与.NET中的行为有所不同。显然用户不应该输入这样的格式。 你可以称之为bug。
答案 1 :(得分:2)
获取分隔符
正如Jeppe Stig Nielson所述(可能是为他投票),没有好办法获得第二个时间或日期分隔符,因为在格式字符串中
HH-mm/HH:mm-HH/mm
可能有多个,即使具有相同的语义(例如,在小时和分钟之间)。
Microsoft错误报告
我已在Microsoft Connect注册并将错误归档为DateTime.ToString("T") and 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;
}
}
}