【问题标题】:convert C# date time to string and back将 C# 日期时间转换为字符串并返回
【发布时间】:2012-06-03 16:00:06
【问题描述】:

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

【问题讨论】:

  • 小点:如果您要使用InvariantCulture 解析字符串,那么您可能也想将InvariantCulture 传递给ToString 方法,只是为了安全起见:now1.ToString(FMT, CultureInfo.InvariantCulture);

标签: c# string datetime data-conversion


【解决方案1】:

如果您想保留DateTime 的值,您应该使用roundtrip format specifier "O" or "o"

“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

【讨论】:

  • 我在使用这种方法时遇到了 UTC 日期问题。请参阅下文了解我是如何修复它的。
【解决方案2】:

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

【讨论】:

  • 这应该是正确的答案。日期类型很重要。
【解决方案3】:

两件事:

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

  2. now1 和 now2 之间仍然会有小的差异,除非您将精度提高到 7 位而不是 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());
    

即使没有上述更改,now1 和 now2 之间的计算差异似乎很小,即使二进制值看起来并不相似。

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

【讨论】:

  • 谢谢。我需要得到完全相同的值,任何差异都会导致单元测试失败,所以最好使用“O”。
【解决方案4】:

如果您不需要人类可读的字符串(例如,您想在存储之前对其进行加密),您可以调用 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());

【讨论】:

    【解决方案5】:

    只需使用此代码将日期时间转换为字符串并将字符串转换为日期时间

    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-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      相关资源
      最近更新 更多