Reputation: 2371
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
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 theDateTime.Parse(String, IFormatProvider, DateTimeStyles)
orDateTime.ParseExact()
method if the styles parameter is set toDateTimeStyles.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
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
Reputation: 333
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
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
Reputation: 10280
2 things:
You can use the ParseExact overload that takes a DateTimeStyle parameter in order to specify AssumeLocal
.
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