Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Set Default Date Format To Date Format From Device Culture

This theoretically tells Xamarin to use the device's culture as the default culture:

CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(CultureInfo.CurrentUICulture.ToString());

You would assume that once this is done, dates would display using the device's culture, but it does absolutely nothing. If you run an app with this code, and display a DateTime.ToString(), it will still be in en-US format.

How do we get the date format to default to the culture of the device?

Best Answer

Answers

  • HunumanHunuman GBMember ✭✭✭✭

    Hi @MelbourneDeveloper

    That is strange, I have never needed to do anything for the app to pick up the device's culture.
    As regards Date.ToString() a format provider is needed.

    Here is a example showing both in action:

    1. The XAML

      <StackLayout>
          <DatePicker x:Name="datePicker" />
          <Button x:Name="btnShow" Clicked="btnShow_Clicked" Text="show date string" />
      </StackLayout>
      
    2. The Code

      public partial class MainPage : ContentPage
      {
          public MainPage()
          {
              InitializeComponent();
          }
      
          private void btnShow_Clicked(object sender, EventArgs e)
          {
              string dateString = this.datePicker.Date.ToString(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern, CultureInfo.CurrentCulture);
              DisplayAlert("The Date", dateString, "OK");
          }
      }
      

    I just tested this on a android device after setting Language and Date format to British in device setting.
    I then exited the app and changed the language to US English and Date format.

    In both cases the date picker and Date.ToString gave the expected output.

    I hope this helps,

    Tim

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭

    @Hunuman , thanks. Yes, I haven't tested this, but I would expect this to work because you are explicitly setting the date format in the ToString() method. But, that's simply not an option for us. We need to format our dates in XAML. We could write a converter to call ToString() in the same way you have, but it's guaranteed that someone who is writing the XAML will leave that out at some point, and the wrong date formats will be displayed to the customer. If dates don't display in the correct date format by default, this is guaranteed to happen. We had this problem in Silverlight for years, and every other week we'd get a bug report saying that someone is complaining about a date in the wrong format. Eventually, we found the line of code that fixes this in Silverlight.

    root.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.Name);
    
  • HunumanHunuman GBMember ✭✭✭✭
    edited August 2017

    Hi @MelbourneDeveloper

    In my example I am not explicitly setting the date format.
    Instead I am setting the date format to be dependent on the current culture.
    This ensures the date formats are aligned to the locale settings of the device.

    Not sure why this would not work in your use case via the converter.
    It is impossible to code away all human errors, that could caught in testing.

    Apologies if I have misunderstood.

    Tim

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭
    You are sort of setting it explicitly. You are getting the date format from the regional settings, and I could do the same thing. It would most likely work, but that doesn't solve my problem. My problem is that all of our UI is in XAML and I would need to specify a converter everywhere to make this work. That's out of my control because I won't be writing all the XAML. People will forget to use the converter and dates will be displayed incorrectly. The system should default to the correct date format. There should be no need to specify an argument to ToString(). In Silverlight for example, this problem was resolved. We don't need to use converters anywhere. It was a huge problem until we found the line of code that fixed it though.
  • HunumanHunuman GBMember ✭✭✭✭
    edited August 2017

    Hi @MelbourneDeveloper

    Thanks for the clarification, that makes sense.
    Sorry I got the wrong end of the stick.

    One option would be to write a extension method to the DateTime structure that encapsulates ToString, but there would still be issues exposing it in XAML.

    Luckily this is not a issue for me as SVOTI handles this for me, but its something for me to bear in mind for any plain old XF apps I may have to build in future.

    Thanks,

    Tim

  • SmeSme USMember ✭✭✭
    edited August 2017

    You should be able to use it like so:

    Text="{Binding Date, StringFormat='{0:d}'}"
    

    You can choose the StringFormat (ie, show the name of the month, or just the digit. Just make sure to use a standard format specifier), and it will automatically localize the date to the proper format (for example, if the culture is simplified Chinese, the above code will output 2017/08/04, US English will output 08/04/2017)

    http://www.csharp-examples.net/string-format-datetime/

    Edit: after looking again, it looks like your issue is setting the current culture. If you just want to use the format given by ToString() (which uses the format of {0:G} I believe), try setting it this way:

    public void SetLocale(CultureInfo ci)
    {
        Thread.CurrentThread.CurrentCulture = ci;
        Thread.CurrentThread.CurrentUICulture = ci;
    }
    

    You'll have to set up the CultureInfo using a dependency service though (for iOS and Android, its done automatically in UWP)

    https://developer.xamarin.com/guides/xamarin-forms/advanced/localization/#Displaying_the_Correct_Language

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭
    edited August 2017

    I will try this. I doubt this will work though. The result of CultureInfo.CurrentUICulture.ToString() is "en-AU" which is correct. It seems that Xamarin recognises what the current UI culture is, but doesn't care.

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭
    edited August 2017

    @Sme, @Hunuman , thanks for you help, but I have come to realise that my problem is different. It turns out that the issue has nothing to do with the default culture. The culture is correctly defaulting to en-AU, and DateTime.ToString() is correctly displaying dates in en-AU format. What is actually going wrong is that somewhere buried in the GetValue/SetValue code in the Xamarin Forms library there is a conversion from DatetTime to string. This code is somehow calling something wrong, and during the conversion it is converting the DateTime from a locale agnostic structure to an en-US formatted date and that is what I am seeing on screen. The problem is easy to replicate. I have documented the bug here:

    https://bugzilla.xamarin.com/show_bug.cgi?id=58635

    Clone the sample repo here: https://[email protected]/ChristianFindlay/xamarin-forms-scratch.git

    You can see the problem clearly here. The first label has the text set manually with ToString(). The other 3 controls are displayed using XF XAML binding.

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭

    Also, correction to the original post:

    You would assume that once this is done, dates would display using the device's culture, but it does absolutely nothing. If you run an app with this code, and display a DateTime.ToString(), it will still be in en-US format.

    This is not the case. DateTime.ToString() is working correctly. It's only binding to string BindableProperties where this is a problem

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭
    Accepted Answer
Sign In or Register to comment.