我正在将C#日期时间转换为字符串。稍后当我将其转换回 DateTime 对象时,它们似乎不相等。
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());
这是一个例子。看起来一切都包含在字符串格式中,当我打印日期时两者显示相同,但是当我比较对象或打印日期的二进制格式时,我看到了差异。这对我来说很奇怪,你能解释一下这里发生了什么吗?
以下是上述代码的输出。
-8588633131198276118
634739049656490000
答案 0 :(得分:40)
如果您想保留DateTime
的值,则应使用roundtrip
format specifier "O" or "o"。
“O”或“o”标准格式说明符表示使用保留时区信息的模式的自定义日期和时间格式字符串。对于DateTime值,此格式说明符旨在保留日期和时间值以及文本中的DateTime.Kind属性。如果styles参数设置为DateTimeStyles.RoundtripKind,则可以使用DateTime.Parse(String,IFormatProvider,DateTimeStyles)或DateTime.ParseExact方法解析格式化的字符串。
使用您的代码(除了更改格式字符串):
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());
我明白了:
-8588633127598789320
-8588633127598789320
答案 1 :(得分:7)
Oded的答案很好,但是对于UTC日期它并不适用。为了使其适用于UTC日期,我需要指定DateTimeStyles值“RoundtripKind”,以便它不会尝试假设它是本地时间。以下是上面的更新代码:
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());
注意,这适用于UTC和本地日期。
答案 2 :(得分:1)
2件事:
您可以使用带有DateTimeStyle参数的ParseExact重载来指定AssumeLocal
。
除非你将精度增加到7位而不是3位,否则now1和now2之间仍然会有一个小的区别:“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());
即使没有上述更改,now1和now2之间的计算差异也很小,即使二进制值看起来不相似。
TimeSpan difference = now2.Subtract(now1);
Console.WriteLine(difference.ToString());
答案 3 :(得分:0)
如果您不需要该字符串易于理解(例如,您想在存储之前对其进行加密),则可以只调用string str = dt1.ToBinary().ToString();
和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());
答案 4 :(得分:-2)
只需使用此代码,即将日期时间转换为字符串,将字符串转换为日期时间
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>"; } } } }