Avatar of Jim Riddles
Jim Riddles
Flag for United States of America asked on

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

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

* WPFC#

Avatar of undefined
Last Comment
Jim Riddles

8/22/2022 - Mon
AndyAinscow

>>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.
Zvonko

Did you try:
var datestring = BeginDate.ToString("yyyy-MM-dd");

Open in new window

Jim Riddles

ASKER
@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."
Your help has saved me hundreds of hours of internet surfing.
fblack61
Jim Riddles

ASKER
@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_saige

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 Riddles

ASKER
@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?
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
AndyAinscow

>>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_saige

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 Riddles

ASKER
@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

This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ASKER CERTIFIED SOLUTION
Jim Riddles

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.