We help IT Professionals succeed at work.

How to format DateTime Field in C# WPF application as yyyy-MM-dd?

Jim Riddles
Jim Riddles asked
on
I am building a C# app to generate codes.  To that end I have created a XAML page to collect the information about the codes to be created.  This page contains two DatePicker fields to indicate when the begin and end dates as to when the code is valid.  However, I need to write this data into a MySQL database, so I need the date to be formatted as yyyy-MM-dd (i.e. 2020-03-10).  After much searching online, I am unable to figure this out.

Here is the code that I have thus far:
GiftCodeGenerator.xaml
<Page x:Class="WSP_USA_Admin_Dashboard.Pages.GiftCodeGenerator"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WSP_USA_Admin_Dashboard.Pages"
      mc:Ignorable="d" 
       Height="Auto" Width="600"
      Title="GiftCodeGenerator">
    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="20*"/>
            <ColumnDefinition Width="25*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="20*"/>
            <ColumnDefinition Width="25*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.ColumnSpan="5" TextWrapping="Wrap" Padding="10">
            Use the below form to generate new gift codes for use on the WSP USA Gift Store.  The Begin and End dates are optional and indicate the dates that the code is valid.  If you leave the begin date empty, it will be valid immediately.  If you leave the end date empty, it will never expire.
        </TextBlock>
        <Label Grid.Column="0" Grid.Row="1" Content="Number of codes*" VerticalAlignment="Center" Margin="5" />
        <TextBox x:Name="CodeQty" Grid.Column="1" Grid.Row="1" Height="25" Margin="5" Width="100" VerticalContentAlignment="Center" />
        <Label Grid.Column="0" Grid.Row="2" Content="PO Number*" VerticalAlignment="Center" Margin="5" />
        <TextBox x:Name="PONumber" Grid.Column="1" Grid.Row="2" Height="25" Margin="5" Width="100" VerticalContentAlignment="Center" />
        <Rectangle Grid.Column="2" Grid.Row="1" Grid.RowSpan="2" VerticalAlignment="Stretch" Fill="LightSlateGray" Width="1" />
        <Label Grid.Column="3" Grid.Row="1" Content="Begin Date" VerticalAlignment="Center" Margin="5" />
        <DatePicker x:Name="BeginDate" Grid.Column="4" Grid.Row="1" Margin="5" Width="100" Height="25" HorizontalAlignment="Left" VerticalAlignment="Center" />
        <Label Grid.Column="3" Grid.Row="2" Content="End Date" VerticalAlignment="Center" Margin="5" />
        <DatePicker x:Name="EndDate" Grid.Column="4" Grid.Row="2" Margin="5" Width="100" Height="25" HorizontalAlignment="Left" VerticalAlignment="Center" />
        <Button x:Name="GenerateCodes" Content="Generate Gift Codes" Grid.ColumnSpan="5" Grid.Row="3" Height="Auto" HorizontalAlignment="Center" Padding="5" Background="DarkRed" Foreground="White" Width="Auto" VerticalAlignment="Center" VerticalContentAlignment="Center" Click="GenerateCodes_Click" />
    </Grid>
</Page>

Open in new window


GiftCodeGenerator.xaml.cs
    private void GenerateCodes_Click(object sender, RoutedEventArgs e)
    {
      if (CodeQty.Text == "" || PONumber.Text == "")
      {
        MessageBox.Show("The quantity and PO Number fields are required!");
        return;
      }
      else
      {
        int numCodes = Convert.ToInt32(CodeQty.Text);
        string poNumber = PONumber.Text;
        string ValidFrom = BeginDate.Text;
        string ValidTo = EndDate.Text;
        MessageBox.Show("The values entered include:\n# codes: " + numCodes.ToString() + "\nPO #: " + poNumber + "\nValid From: " + ValidFrom + "\nValid To: " + ValidTo);
      }
    }

Open in new window


Currently, the date looks like "03/10/2020".  I have tried the following example I found online, but got an error about no method of "Value".
var datestring = datePicker.Value.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);

Open in new window

Comment
Watch Question

AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT

Commented:
>>However, I need to write this data into a MySQL database, so I need the date to be formatted as yyyy-MM-dd

You really should store the date as a date in the database, not as a string as this requirement hints at.
ZvonkoSystems architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
Did you try:
var datestring = BeginDate.ToString("yyyy-MM-dd");
Jim RiddlesPrepress/OMS Specialist
CERTIFIED EXPERT

Author

Commented:
@AndyAinscow
I am using a field type of date in my MySQL table, however it is my belief that the date needs to be formatted correctly to be able to be injected in the table.  Is that not the case?  Are you saying that I can just use the value of the DatePicker as-is when I insert it into my database?  If so, that makes this much easier than I thought it would be.

@Zvonko
How do I do that with the value of the DatePicker field?  When I try to use your example in my page I get a warning "No overload for method 'ToString' takes 1 arguments."
Jim RiddlesPrepress/OMS Specialist
CERTIFIED EXPERT

Author

Commented:
@Zvonko
After a bit of tinkering, I found that your statement was missing a bit of information.  The following code works perfectly.
BeginDate.SelectedDate.Value.ToString("yyyy-MM-dd");

Open in new window

Note that I had to access SelectedDate to get the Value method.
it_saigeDeveloper
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
You could accomplish this individually by setting the SelectedDate property; e.g. -
<DatePicker SelectedDate="{Binding PropertyName, StringFormat=yyyy-MM-dd}"/>

Open in new window

You could also add a style to to either your xaml (for the single page/form) or to your App.xaml (for all of your DatePicker controls):
<Style TargetType="{x:Type DatePickerTextBox}">
 <Setter Property="Control.Template">
  <Setter.Value>
   <ControlTemplate>
    <TextBox x:Name="PART_TextBox"
     Text="{Binding Path=SelectedDate, StringFormat='yyyy-MM-dd', 
     RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}" />
   </ControlTemplate>
  </Setter.Value>
 </Setter>
</Style>

Open in new window

-saige-
Jim RiddlesPrepress/OMS Specialist
CERTIFIED EXPERT

Author

Commented:
@it_saige
I tried your first example by altering my XAML to the following, but it does not appear to have worked.  When I use MessageBox.Show(BeginDate.SelectedDate.ToString()); it displays the full date with the time.
<DatePicker x:Name="BeginDate" Grid.Column="4" Grid.Row="1" Margin="5" Width="100" Height="25" HorizontalAlignment="Left" VerticalAlignment="Center" SelectedDate="{Binding PropertyName, StringFormat=yyyy-MM-dd}" />

Open in new window

What did I do wrong?
AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT

Commented:
>>however it is my belief that the date needs to be formatted correctly to be able to be injected in the table. 

OK, thanks for clarifying.  (One sees numbers of questions here where the asker talks about a date in a database but in reality has a string - the stored date could be hello world !  With the corresponding problems that causes.)  

A date actually has no formatting information so you can 'inject' a date directly.  A 'formatted date' is in reality a (human readable) string representing a date.
it_saigeDeveloper
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
My apologies Jim, I should have clarified that PropertyName was a place holder.  It needs to be replaced with the name of the property.  In your case I believe this would be BeginDate in one and EndDate in the other.

-saige-
Jim RiddlesPrepress/OMS Specialist
CERTIFIED EXPERT

Author

Commented:
@it_saige
I just got around to trying your method again, and it still did not work.  This is what I was trying to use, but when I reference BeginDate, it still displays as MM/dd/yyyy.  I am just going to stick with what worked and be done with this question.  Thanks for your help!
<DatePicker x:Name="BeginDate" Grid.Column="4" Grid.Row="1" Margin="5" Width="100" Height="25" HorizontalAlignment="Left" VerticalAlignment="Center" SelectedDate="{Binding BeginDate, StringFormat=yyyy-MM-dd}" />

Open in new window

Prepress/OMS Specialist
CERTIFIED EXPERT
Commented:
Working off of Zvonko's solution, I was able to figure out the rest.  Thank you all for your assistance.  Below is the final working solution.

BeginDate.SelectedDate.Value.ToString("yyyy-MM-dd");

Open in new window

Explore More ContentExplore courses, solutions, and other research materials related to this topic.