66

I mean to store strict UTC time in a DateTime variable and output it in ISO 8601 format.

To do the last I've used .ToString("yyyy-MM-ddTHH:mm:sszzz"), and it has uncovered that the time zone is UTC+01:00.

I've tried to use .Kind = DateTimeKind.Utc, but it says the Kind property has no setter.

How do I explicitly specify the time is in UTC? How is the Kind property set?

fphilipe
  • 9,739
  • 1
  • 40
  • 52
Ivan
  • 63,011
  • 101
  • 250
  • 382

4 Answers4

74

If you want to get advantage of your local machine timezone you can use myDateTime.ToUniversalTime() to get the UTC time from your local time or myDateTime.ToLocalTime() to convert the UTC time to the local machine's time.

// convert UTC time from the database to the machine's time
DateTime databaseUtcTime = new DateTime(2011,6,5,10,15,00);
var localTime = databaseUtcTime.ToLocalTime();

// convert local time to UTC for database save
var databaseUtcTime = localTime.ToUniversalTime();

If you need to convert time from/to other timezones, you may use TimeZoneInfo.ConvertTime() or TimeZoneInfo.ConvertTimeFromUtc().

// convert UTC time from the database to japanese time
DateTime databaseUtcTime = new DateTime(2011,6,5,10,15,00);
var japaneseTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
var japaneseTime = TimeZoneInfo.ConvertTimeFromUtc(databaseUtcTime, japaneseTimeZone);

// convert japanese time to UTC for database save
var databaseUtcTime = TimeZoneInfo.ConvertTimeToUtc(japaneseTime, japaneseTimeZone);

List of available timezones

TimeZoneInfo class on MSDN

SandRock
  • 5,276
  • 3
  • 30
  • 49
49

While the DateTime.Kind property does not have a setter, the static method DateTime.SpecifyKind creates a DateTime instance with a specified value for Kind.

Altenatively there are several DateTime constructor overloads that take a DateTimeKind parameter

Frank Boyne
  • 4,400
  • 23
  • 30
  • 4
    The `DateTimeKind` only contains local, unspecified and UTC. It is probably not possible I want to using one particular time zone. – hardywang Mar 09 '15 at 20:10
  • 4
    @hardywang If all you need is to specify a time and an offset from UTC then you can use [DateTimeOffset](https://msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx). If you really need to identify a particular time zone then you need to combine DateTime with a [TimeZoneInfo](https://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx). See [Choosing Between DateTime, DateTimeOffset, and TimeZoneInfo](https://msdn.microsoft.com/en-us/library/bb384267.aspx) for a discussion. – Frank Boyne Mar 15 '15 at 05:53
  • DateTimeKind does not really do a great deal other than act as a point of reference when converting times. It does not actually change anything if you apply it to an existing DateTime. – onefootswill Dec 18 '21 at 04:39
13

You can try this as well, it is easy to implement

TimeZone time2 = TimeZone.CurrentTimeZone;
DateTime test = time2.ToUniversalTime(DateTime.Now);
var singapore = TimeZoneInfo.FindSystemTimeZoneById("Singapore Standard Time");
var singaporetime = TimeZoneInfo.ConvertTimeFromUtc(test, singapore);

Change the text to which standard time you want to change.

Use TimeZone feature of C# to implement.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Sandeep Nair
  • 131
  • 1
  • 2
1

I hit the time zone problem in System.DateTime in net framework 4.8. I suppose there's a bug in this version of framework.

I ran this piece of code under net framework 4.8 and net 5.0 (+3 is my local time zone).

var dateTime = new DateTime(2021, 3, 3, 12, 13, 14);
var dateTimeKindUtc = new DateTime(2021, 3, 3, 12, 13, 14, DateTimeKind.Utc);
var dateTimeSpecifyKind = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
var dateTimeToUniversalTime = dateTime.ToUniversalTime();
var timeZoneInfoConvertTimeToUtc = TimeZoneInfo.ConvertTimeToUtc(dateTime);

Console.WriteLine($"{nameof(dateTime)} {dateTime:yyyy-MM-ddTHH:mm:sszzz}");
Console.WriteLine($"{nameof(dateTimeKindUtc)} {dateTimeKindUtc:yyyy-MM-ddTHH:mm:sszzz}");
Console.WriteLine($"{nameof(dateTimeSpecifyKind)} {dateTimeSpecifyKind:yyyy-MM-ddTHH:mm:sszzz}");
Console.WriteLine($"{nameof(dateTimeToUniversalTime)} {dateTimeToUniversalTime:yyyy-MM-ddTHH:mm:sszzz}");
Console.WriteLine($"{nameof(timeZoneInfoConvertTimeToUtc)} {timeZoneInfoConvertTimeToUtc:yyyy-MM-ddTHH:mm:sszzz}");

net framework 4.8 output

dateTime 2021-03-03T12:13:14+03:00
dateTimeKindUtc 2021-03-03T12:13:14+03:00
dateTimeSpecifyKind 2021-03-03T12:13:14+03:00
dateTimeToUniversalTime 2021-03-03T09:13:14+03:00
timeZoneInfoConvertTimeToUtc 2021-03-03T09:13:14+03:00

net 5.0 output

dateTime 2021-03-03T12:13:14+03:00
dateTimeKindUtc 2021-03-03T12:13:14+00:00
dateTimeSpecifyKind 2021-03-03T12:13:14+00:00
dateTimeToUniversalTime 2021-03-03T09:13:14+00:00
timeZoneInfoConvertTimeToUtc 2021-03-03T09:13:14+00:00
AlexAlum
  • 347
  • 1
  • 9
  • 19
  • 1
    From the [docs](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings#zzzSpecifier): 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 doesn't 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.** – Vegard Løkken Jan 07 '22 at 08:11