safary
safary

Reputation: 325

c# making a short date ends up adding one day

I am trying to make a short date, but in the result I get one day more. With date like "2014-01-03 00:00:00" its okay, but it fails when time is "23:59:59".

EntryDate= "2014-01-03 23:59:59"

but getting result = "2014-01-04"

  try
        {
            DateTime exact = DateTime.ParseExact(EntryDate, "yyyyMMdd", (IFormatProvider)CultureInfo.InvariantCulture);
            mventryAttrib.Value = (exact.ToLocalTime().ToString("yyyy-MM-dd"));
        }
        catch (FormatException ex)
        {
            try
            {
                DateTime exact = DateTime.ParseExact(EntryDate, "yyyy-MM-dd HH:mm:ss", (IFormatProvider)CultureInfo.InvariantCulture);
                mventryAttrib.Value = (exact.ToLocalTime().ToString("yyyy-MM-dd"));
            }
            catch
            {
            }

Upvotes: 1

Views: 1201

Answers (3)

Lasse V. Karlsen
Lasse V. Karlsen

Reputation: 391276

This is due to ParseExact returns a DateTime with a Kind property value of DateTimeKind.Unspecified.

This, when coupled with a call to .ToLocalTime() when you're in a timezone that has a positive offset from UTC, will bump the DateTime value forward by that many hours and return a DateTime value with a Kind property value of DateTimeKind.Local.

Here is a short program that will demonstrate:

var exact = DateTime.ParseExact("2014-01-03 23:59:59", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
Console.WriteLine($"{exact} - {exact.Kind}");

var local = exact.ToLocalTime();
Console.WriteLine($"{local} - {local.Kind}");

Console.WriteLine(TimeZone.CurrentTimeZone.GetUtcOffset(exact));

Output (on my machine):

03.01.2014 23.59.59 - Unspecified
04.01.2014 00.59.59 - Local
01:00.00

If you intended the parsed DateTime value to be local from the outset you should make a new value that is specifically local, with the same values:

exact = new DateTime(exact.Ticks, DateTimeKind.Local);

Be aware though that this may have unforseen consequences when dealing with timezone boundaries. I would urge you to find a better library than the built in DateTime types, such as Noda Time.

Upvotes: 4

Matti9811
Matti9811

Reputation: 52

I think this site could help you to solve the problem.

https://msdn.microsoft.com/en-gb/library/8kb3ddd4(v=vs.110).aspx

Upvotes: 0

Code Gorilla
Code Gorilla

Reputation: 971

It looks as though you are setting the time in exact as a UTC time and then converting this to a local time. This conversion is adding a number of hours to the time and consequently moving the date along.

Try exact.ToUniversalTime() and you should get the date you set.

Upvotes: 1

Related Questions