Link to home
Start Free TrialLog in
Avatar of Jim Riddles
Jim RiddlesFlag 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

Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

>>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.
Did you try:
var datestring = BeginDate.ToString("yyyy-MM-dd");

Open in new window

Avatar of 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."
@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.
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-
@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?
>>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.
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-
@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

ASKER CERTIFIED SOLUTION
Avatar of Jim Riddles
Jim Riddles
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial