Подтвердить что ты не робот

Конвертировать дату С# в строку и обратно

Я конвертирую дату даты С# в строку. Позже, когда я конвертирую его в объект 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
4b9b3361

Ответ 1

Вы должны использовать roundtrip спецификатор формата "o" или "o" , если вы хотите сохранить значение DateTime.

Спецификатор стандартного формата "O" или "o" представляет собой пользовательскую строку формата даты и времени с использованием шаблона, который сохраняет информацию о часовом поясе. Для значений DateTime этот спецификатор формата предназначен для сохранения значений даты и времени вместе с свойством DateTime.Kind в тексте. Отформатированную строку можно проанализировать с помощью метода DateTime.Parse(String, IFormatProvider, DateTimeStyles) или DateTime.ParseExact, если для параметра styles установлено значение DateTimeStyles.RoundtripKind.

Использование вашего кода (кроме изменения строки формата):

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

Ответ 2

Отложенный ответ хорош, но он не работает для меня для дат 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

2 вещи:

  • Вы можете использовать перегрузку ParseExact, которая принимает параметр DateTimeStyle, чтобы указать AssumeLocal.

  • По-прежнему будет небольшая разница между 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());

Ответ 4

Просто используйте этот код, чтобы преобразовать дату в строку и строку в дату

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>";
            }
        }
    }
}