axe
axe

Reputation: 2371

convert C# date time to string and back

I'm converting C# date time to string. Later when I convert it back to DateTime object it appears that they are not equal.

const string FMT = "yyyy-MM-dd HH:mm:ss.fff";
DateTime now1 = DateTime.Now;
string strDate = now1.ToString(FMT);
DateTime now2 = DateTime.ParseExact(strDate, FMT, CultureInfo.InvariantCulture);
Console.WriteLine(now1.ToBinary());
Console.WriteLine(now2.ToBinary());

Here is the example. Looks like everything is included in string format, when I print date both displays the same, but when I compare objects or print date in binary format I see the difference. It looks strange to me, could you please explain what is going on here?

Here is the output for the code above.

-8588633131198276118
634739049656490000

Upvotes: 34

Views: 46398

Answers (5)

Oded
Oded

Reputation: 499262

You should use the roundtrip format specifier "O" or "o" if you want to preserve the value of the DateTime.

The "O" or "o" standard format specifier represents a custom date and time format string using a pattern that preserves time zone information. For DateTime values, this format specifier is designed to preserve date and time values along with the DateTime.Kind property in text. The formatted string can be parsed back by using the DateTime.Parse(String, IFormatProvider, DateTimeStyles) or DateTime.ParseExact() method if the styles parameter is set to DateTimeStyles.RoundtripKind.

Using your code (apart from changing the format string):

const string FMT = "O";
DateTime now1 = DateTime.Now;
string strDate = now1.ToString(FMT);
DateTime now2 = DateTime.ParseExact(strDate, FMT, CultureInfo.InvariantCulture);
Console.WriteLine(now1.ToBinary());
Console.WriteLine(now2.ToBinary());

I get:

-8588633127598789320
-8588633127598789320

Upvotes: 51

Jan 'splite' K.
Jan 'splite' K.

Reputation: 2114

If you dont need the string to be human-readable (like, you want to cipher it before storage), you can just call string str = dt1.ToBinary().ToString(); and DateTime dt2 = DateTime.FromBinary(long.Parse(str));

DateTime now1 = DateTime.Now;
string strDate = now1.ToBinary().ToString();
DateTime now2 = DateTime.FromBinary(long.Parse(strDate));
Console.WriteLine(now1.ToBinary());
Console.WriteLine(now2.ToBinary());

Upvotes: 2

Just use this code it convert date time to string and string to date time

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace DateTimeConvert
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
              label1.Text = ConvDate_as_str(textBox1.Text);
        }

        public string ConvDate_as_str(string dateFormat)
        {
            try
            {
                char[] ch = dateFormat.ToCharArray();
                string[] sps = dateFormat.Split(' ');
                string[] spd = sps[0].Split('.');
                dateFormat = spd[0] + ":" + spd[1] + " " + sps[1];
                DateTime dt = new DateTime();
                dt = Convert.ToDateTime(dateFormat);
                return dt.Hour.ToString("00") + dt.Minute.ToString("00");
            }
            catch (Exception ex)
            {
                return "Enter Correct Format like <5.12 pm>";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            label2.Text = ConvDate_as_date(textBox2.Text);
        }

        public string ConvDate_as_date(string stringFormat)
        {
            try
            {
                string hour = stringFormat.Substring(0, 2);
                string min = stringFormat.Substring(2, 2);
                DateTime dt = new DateTime();
                dt = Convert.ToDateTime(hour+":"+min);
                return String.Format("{0:t}", dt); ;
            }
            catch (Exception ex)
            {
                return "Please Enter Correct format like <0559>";
            }
        }
    }
}

Upvotes: -2

Taylor Lafrinere
Taylor Lafrinere

Reputation: 3104

Oded's answer is good but it didn't work for me for UTC dates. In order to get it to work for UTC dates, I needed to specify a DateTimeStyles value of "RoundtripKind" so that it didn't try to assume it was a local time. Here is the updated code from above:

const string FMT = "O";
DateTime now1 = DateTime.Now;
string strDate = now1.ToString(FMT);
DateTime now2 = DateTime.ParseExact(strDate, FMT, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
Console.WriteLine(now1.ToBinary());
Console.WriteLine(now2.ToBinary());

Note, this works for both UTC and local dates.

Upvotes: 20

Dr. Wily&#39;s Apprentice
Dr. Wily&#39;s Apprentice

Reputation: 10280

2 things:

  1. You can use the ParseExact overload that takes a DateTimeStyle parameter in order to specify AssumeLocal.

  2. There will still be a small difference between now1 and now2 unless you increase the precision to 7 digits instead of 3: "yyyy-MM-dd HH:mm:ss.fffffff"

        const string FMT = "yyyy-MM-dd HH:mm:ss.fffffff";
        DateTime now1 = DateTime.Now;
        string strDate = now1.ToString(FMT);
        DateTime now2 = DateTime.ParseExact(strDate, FMT, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal);
        Console.WriteLine(now1.ToBinary());
        Console.WriteLine(now2.ToBinary());
    

Even without the above changes, the calculated difference between now1 and now2 appears small, even though the binary values do not appear similar.

        TimeSpan difference = now2.Subtract(now1);
        Console.WriteLine(difference.ToString());

Upvotes: 2

Related Questions