0

I have date on format 11/19/2017 12:00:40 AM and I want to transform it to 2017/11/19 12:00:40 AM

var d = DateTime.ParseExact("11/19/2017 12:00:40 AM", "M/d/yyyy hh:mm:ss tt", 
    CultureInfo.InvariantCulture).ToString("yyyy/M/d hh:mm:ss tt");

var dt = DateTime.ParseExact(d, "yyyy/M/d hh:mm:ss tt", CultureInfo.InvariantCulture);

value of d is actually 2017/11/19 12:00:40 AM but it's string. In db I must write it as yyyy/M/d hh:mm:ss tt.

But result of dt is anyway the old value.

enter image description here

What's wrong?

gsiradze
  • 4,583
  • 15
  • 64
  • 111
  • 5
    `DateTime` doesn't have a format - the debugger is just showing you the default way that it would be formatted, but that's not part of the value. If you want to format it in a particular way, you need to keep it as a string. – Jon Skeet Apr 27 '18 at 15:12
  • 2
    Wrong is your expectation that a DateTime has a format. What the debugger presents you is already formatted. A DateTime has just a value. – Tim Schmelter Apr 27 '18 at 15:12
  • A DateTime is a _moment_ of time. There is no format there, its some number of ticks from an epoch. When you display that DateTime as a _string_ you can format it in a seemingly endless number of ways. After all you should only care about the format when you are dealing with strings, why do you care what format the DateTime has internally? You can never display its value until you turn it into a string – maccettura Apr 27 '18 at 15:16
  • The various formats written are get using `ToString()` methods, which has overloads to specify culture info, among other things - but that's only for display, though. Any comparison and operations will use the internal (culture independant) representation. – Pac0 Apr 27 '18 at 15:16
  • @gsiradze I **love** [this answer](https://stackoverflow.com/a/24728080/9453080) – Ivan García Topete Apr 27 '18 at 15:23

2 Answers2

1

You are running into representation of a value vs the actuall value.

In reality all dateTimes are a unsigned Int64 counting the number of Ticks since "point X" (wich is usually the start of the Unix Time, 1st Janurary 1970, 00:00:00). But users can not work with that. They need a human readable string format. Wich is also different between Langauges, much less Cultural regions. UK and US both speak english, but can not decide if the month or day should come first.

Both the ToString() and Parse() functions are designed to automagically extract the proper way a Number should look as string from the Region settings of Windows. The ToString() function that is part of the Debugger is no exception.

Christopher
  • 9,634
  • 2
  • 17
  • 31
0

DateTime is backed by a number (ticks). It has no human-readable representation, at all! When you create a DateTime (by specifying each date component individually, or by parsing a date string), it converts the string date into a ticks.

So what are you seeing in the debugger? Well, that's the result of the DateTime object's default ToString() method. This depends on the culture of the thread which the code is running in. Unless you change it, it will be the same as the operating system culture by default.

Likewise, this culture is also used when parsing dates, so in the UK 5/1/2018 would be understood by DateTime.Parse(...) as the 5th of January, 2018, whereas in the US it would be understood as the 1st of May, 2018.

How should you use this information?

  1. Understand that the date format used in the debugger is based on your computer's culture, and it means nothing as to how the DateTime object will perform on computers in other cultures.

  2. If you want to display the date to a user, you need to use the ToString() methods (there are a few overloads) to produce a date formatted the way you want it to be. Of course, the parameterless ToString() method will work fine if you just want it formatted for the end-user's culture.

  3. If you need to send a specific format, again you should use one of the ToString() overloads. For example, you can pass the format o: DateTime.UtcNow.ToString("o"), and it will print the date in an ISO8601 compliant format: 2018-04-28T15:31:00.000Z

You can find different format strings here (MS docs).


One last thing: "In db I must write it as yyyy/M/d hh:mm:ss tt."

If you are using an SQL database (SQL Server, MySQL, etc.) and you are using a date-typed field in the database, you should build your SQL queries using parameters. You wouldn't need to format the date at all then, you could just pass the DateTime object as a parameter.

See here for more information on the SQL injection vulnerability and how to use parameterized queries.

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86