I wanna combine Gusman's and Evan's comments and create some arguments against them if they let me. Let's take step by step..
Should DateTime.UtcNow
have a timezone offset?
No matter what Kind
it has (Local, Utc or Unspecified), a DateTime
instance does not keep any UTC offset value. Period.
First of all, let's take a look at the The "zzz"
format specifier documentation;
With DateTime values, the "zzz" custom format specifier represents the
signed offset of the local operating system's time zone from UTC,
measured in hours and minutes. It does not reflect the value of an
instance's DateTime.Kind property. For this reason, the "zzz" format
specifier is not recommended for use with DateTime values.
Based on first two bold sentences, both result generated by LINQPad is totally expected. You can get the same results (expect date and time parts of course) in Visual Studio as well.
Just run this code as "Start Without Debugging" (Ctrl + F5)
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"));
Console.WriteLine(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:sszzz"));
But what about when you run it as "Start Debugging" with (F5)?
There are two option in such a case which depends on your DateTimeInvalidLocalFormat
in Managed Debugging Assistants is ticked or not. This sections is on the Debug
menu, then click Exceptions
.

If this option is ticked, you get an exception and it says;
A UTC
DateTime is being converted to text in a format that is only
correct for local times. This can happen when calling
DateTime.ToString
using the 'z'
format specifier, which will include a
local time zone offset in the output. In that case, either use the 'Z'
format specifier, which designates a UTC time, or use the 'o'
format
string, which is the recommended way to persist a DateTime in text.
If this option is not ticked, you won't get any message and the result will be the same as LINQPad.
Given that the 2nd result is universal time, I expected it to return
2016-01-08T16:05:04-00:00
(timezone offset of zero).
As I explained, zzz
format specifier does not behave like that for any DateTime
instance.
But it behaves differently for a DateTimeOffset
instance which is documented as;
With DateTimeOffset
values, this format specifier represents the
DateTimeOffset value's Offset
from UTC in hours.
And DateTimeOffset.Now
and DateTimeOffset.UtcNow
are perfectly fits your expectation no matter you run in LINQPad or Visual Studio since they are documented as;
Now
A DateTimeOffset object whose date and time is the current local time
and whose offset is the local time zone's offset from Coordinated
Universal Time (UTC).
UtcNow
An object whose date and time is the current Coordinated Universal
Time (UTC) and whose offset is TimeSpan.Zero
.
Console.WriteLine(DateTimeOffset.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"));
Console.WriteLine(DateTimeOffset.UtcNow.ToString("yyyy-MM-ddTHH:mm:sszzz"));
would generate
2016-01-08T09:05:04-07:00
2016-01-08T16:05:04-00:00
Tl;dr I think this is not a bug. LINQPad generates the right results exactly what it should be. In Visual Studio, you might get an exception if that option is ticked or not in debugging mode.