32

我正在将 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
4

5 回答 5

46

如果要roundtrip保留DateTime.

“O”或“o”标准格式说明符表示使用保留时区信息的模式的自定义日期和时间格式字符串。对于 DateTime 值,此格式说明符旨在保留日期和时间值以及文本中的 DateTime.Kind 属性。如果样式参数设置为 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
于 2012-05-29T12:19:20.947 回答
19

Oded 的回答很好,但它不适用于 UTC 日期。为了让它适用于 UTC 日期,我需要指定“RoundtripKind”的 DateTimeStyles 值,这样它就不会试图假设它是本地时间。这是上面的更新代码:

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 和本地日期。

于 2016-12-31T18:27:52.077 回答
2

2件事:

  1. 您可以使用带有 DateTimeStyle 参数的 ParseExact 重载来指定AssumeLocal.

  2. 除非您将精度提高到 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());
于 2012-05-29T12:37:22.690 回答
2

如果您不需要字符串是人类可读的(例如,您想在存储之前对其进行加密),您可以调用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());
于 2018-10-09T15:42:15.927 回答
-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>";
            }
        }
    }
}
于 2012-11-05T06:48:55.353 回答