I'm based in the UK, and my computer always shows a UK date format (dd/mm/yyyy).
My WPF project is, for some reason converting my DateTime format to US type. This occurs on my work machine and home machine.
I've been able to replicate the issue very simply
<Window x:Class="TimeIssues.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Text="{Binding MyTime}"></TextBlock> <!-- the value is 1/28/2014 10:15:37 (note it is M/dd/yyyy....)
</Grid>
</Window>
And in the code behind, simply
public partial class MainWindow : Window
{
public MainWindow()
{
SetMyTime("28/01/2014 10:15:37"); //note, this is dd/MM/yyyy .... format
this.DataContext = this;
InitializeComponent();
}
private void SetMyTime(string dateTime)
{
DateTime dt;
DateTime.TryParseExact(dateTime, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
MyTime = dt; // the value is expected, showing 28/01/2014 10:15:37
}
public DateTime MyTime { get; set; }
}
Just to confirm that this isn't an IT issue (or so I think), my PC is set for UK (and the Location is also set to UK as is the Current language for non-unicode programs)
I have read WPF format DateTime in TextBlock? but this won't help (I don't think) as that question is about setting the format when the format is known.
If I update my MyTime from DateTime
to a string
, then the result is expected (UK format)! The issue is WPF changes the format when the type is DateTime which is not desired!
My issue is 2 fold -
How do I tell WPF to use the user's locale settings? Is there any way to read the OS settings (as per the screen shot above)?
Datetime data types are used to store date and time information. The DATE data type consists of year, month, and day information to represent a date value. The default format for the DATE data type is YYYY-MM-DD. YYYY represents the year, MM represents the month, and DD represents the day.
The ToString() method of the DateTime class is used to convert a DateTime date object to string format. The method takes a date format string that specifies the required string representation.
ParseExact(dateLiteral, "d", new CultureInfo("en-US")); var dateLiteral = "8/24/2017"; var date = DateTime. ParseExact(dateLiteral, "d", new CultureInfo("en-US")); Here we use the short date standard format specifier d to parse a string literal.
The "ddd" custom format specifier represents the abbreviated name of the day of the week. The localized abbreviated name of the day of the week is retrieved from the DateTimeFormatInfo.AbbreviatedDayNames property of the current or specified culture.
CultureInfo
is picked from Thread's current culture which in your case will be set to en-US
. You need to set it to en-GB
like this:
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-GB");
But when you set this you will see, XAML doesn't pick this. For XAML to pick it you have to override FrameworkElement.LanguageProperty
metadata.
Override OnStartup()
method in your App.xaml.cs
and place this code there and you are good to go:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-GB");
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-GB");
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
}
UPDATE
Is there any way to read the OS settings (as per the screen shot above)?
In case you want to pick CultureInfo
based on the format selected for system, you can do that as well by getting LCID for OS. This is how you do it:
[DllImport("kernel32.dll")]
private static extern int GetUserDefaultLCID();
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
int machineLCID = GetUserDefaultLCID();
CultureInfo machineCultureInfo = CultureInfo.GetCultureInfo(machineLCID);
Thread.CurrentThread.CurrentUICulture = machineCultureInfo;
Thread.CurrentThread.CurrentCulture = machineCultureInfo;
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With