5

I want DateTime in the following format.

DateTime a = Convert.ToDateTime(DateTime.UtcNow.ToString("s") + "Z");

Output:

2018-05-29T09:16:59Z

I want to subtract 4 hours from this time. So I have used this line of code:

var result = a.AddHours(-4);

Now, not only is the wrong time being shown, the above format is also disturbed.

29-05-2018 10:52:51

Expected Output:

2018-05-29T05:16:59Z
Hello
  • 84
  • 6
  • How do you display the time after subtraction? – PepitoSh May 29 '18 at 09:30
  • 6
    Ill vote this up, because its the first newbie question in the last 2 hours that has remotely made sense, that has good formatting, that shows a least some effort, and isn't just asking to do your homework – TheGeneral May 29 '18 at 09:30
  • 3
    "the above format is also disturbed" - a DateTime has no format. You only have a format when you convert it to a string using something like `ToString()`. When you are doing this however you immediately parse it back into a DateTime which has no format. You will need to specify the format you want any time you convert it to a string in any way (either via `ToString` or in `String.Format` or similar). – Chris May 29 '18 at 09:36
  • 1
    A `DateTime` structure only contains a count of the number of 100 nanosecond intervals that have elapsed since midnight at the start of 01/01/0001. It doesn't contain any *strings*, it doesn't *have* a format. Formats apply *when converting to and from strings* and **are not** an inherent property of a datetime. – Damien_The_Unbeliever May 29 '18 at 09:40
  • 1
    Always avoid stringly typing. The hack with the "Z" does not actually give you the format you want, the DateTime.Kind is still Local. Get ahead with a = DateTime.UtcNow so the Kind is set right. Some odds that you no longer have to correct the hour. Generate the string at the last possible moment with ToString(), now you can append "Z" if you want it. – Hans Passant May 29 '18 at 09:43
  • @PepitoSh, I want to display records from database table from the last 4 hours. So on page load, I can capture those 2 'times' and use them in an SQL query. TheGeneral, thanks :-) – Hello May 29 '18 at 09:44
  • Yes, so use `DateTime` typed values throughout your C# and SQL code (using parameters so that ADO.Net applies appropriate conversions) and **avoid** strings as much as possible, to avoid any formatting "issues". – Damien_The_Unbeliever May 29 '18 at 09:55

2 Answers2

1

To get UTCNow minus 4 hours you'd want to do:

var fourHoursAgo = DateTime.UtcNow.AddHours(-4);
Console.WriteLine("fourHoursAgo: " + fourHoursAgo.ToString("yyyy-MM-ddTHH:mm:ssK"));

This will give an output like:

2018-05-29T05:36:18Z

This is basically an ISO 8601 format, very similar to DateTime.ToString("s"), but including the timezone ("Z" in this case.)

Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
  • 1
    Thanks a lot. Instead of .ToString("o");, I have used var result = DateTime.UtcNow.AddHours(-4).ToString("s") + "Z"; – Hello May 29 '18 at 09:41
  • Cool, that should work. This page is useful if you havent' seen it before: https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings – Terry Lennox May 29 '18 at 09:45
0

I think the problem you are facing here is the conversion between different time zones:

//Saves the time in your own timezone
DateTime a = Convert.ToDateTime(DateTime.UtcNow.ToString("s") + "Z");
var result = a.AddHours(-4);
//1h @ middle europe (berlin,...)
Console.WriteLine("Local Timezone offset: " + TimeZoneInfo.Local.BaseUtcOffset);
//not mentioned above: + 1h daylight saving time in germany

//local times
System.Console.WriteLine("local:\t\t" + a.ToString("s")); //2018-05-29T12:34:26
System.Console.WriteLine("local -4h:\t" + result.ToString("s")); //2018-05-29T08:34:26

//utc times
System.Console.WriteLine("utc:\t\t" + DateTime.UtcNow.ToString("s")); //2018-05-29T10:34:26
var utctime = TimeZoneInfo.ConvertTime(result, TimeZoneInfo.Utc);
System.Console.WriteLine("utc -4h:\t" + utctime.ToString("s")); //2018-05-29T06:34:26

As you can see, the first line saves your date and return it on ToString("s") in your local timezone, not utc timezone. This caused most likely the confusion as you had a utc time format as input.

I'm from germany and got my local timezone UTC +01:00h.

For more info read this answer.

Chrᴉz remembers Monica
  • 1,829
  • 1
  • 10
  • 24