runtime: `DateTime.Now` on Linux has wrong timezone

Description

When use DateTime.Now on my Linux machine, dotnet assume the timezone is UTC.

Reproduction Steps

Using Ubuntu 20.04:

$ timedatectl status
               Local time: 五 2021-10-15 21:07:22 CST
           Universal time: 五 2021-10-15 13:07:22 UTC
                 RTC time: 五 2021-10-15 13:07:22    
                Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes                       
              NTP service: active                    
          RTC in local TZ: no

However the code:

DateTime localNow = DateTime.Now;
DateTime utcNow = DateTime.UtcNow;
Console.WriteLine($"localNow: {localNow}, {localNow.Kind}, utcNow: {utcNow}, {utcNow.Kind}");
Console.WriteLine($"TimeZoneInfo.Local: {TimeZoneInfo.Local}");

Produces output:

localNow: 10/15/2021 13:07:25, Local, utcNow: 10/15/2021 13:07:25, Utc
TimeZoneInfo.Local: (UTC) Coordinated Universal Time

Expected behavior

DateTime.Now has the proper local time.

Actual behavior

DateTime.Now always equal to UTC time, no matter what the system timezone is.

Regression?

No response

Known Workarounds

No response

Configuration

Using dotnet sdk 6.0.100-rc.1.21463.6 on Linux (Ubuntu 20.04).

$ dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.100-rc.1.21463.6
 Commit:    e627d556a1

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  20.04
 OS Platform: Linux
 RID:         ubuntu.20.04-x64
 Base Path:   /opt/dotnet/sdk/6.0.100-rc.1.21463.6/

Host (useful for support):
  Version: 6.0.0-rc.1.21451.13
  Commit:  d7619cd4b1

.NET SDKs installed:
  5.0.401 [/opt/dotnet/sdk]
  6.0.100-rc.1.21463.6 [/opt/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 5.0.10 [/opt/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-rc.1.21452.15 [/opt/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 5.0.10 [/opt/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.0-rc.1.21451.13 [/opt/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download

Other information

UPDATE: I found this issue may relate to RTC settings:

$ timedatectl set-local-rtc 1 --adjust-system-clock
$ sudo reboot
...
$ timedatectl status
               Local time: 五 2021-10-15 23:25:15 CST
           Universal time: 五 2021-10-15 15:25:15 UTC
                 RTC time: 五 2021-10-15 15:25:16    
                Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes                       
              NTP service: active                    
          RTC in local TZ: yes                       

Warning: The system is configured to read the RTC time in the local time zone.
         This mode cannot be fully supported. It will create various problems
         with time zone changes and daylight saving time adjustments. The RTC
         time is never updated, it relies on external facilities to maintain it.
         If at all possible, use RTC in UTC by calling
         'timedatectl set-local-rtc 0'.
$ dotnet run
localNow: 10/15/2021 23:25:25, Local, utcNow: 10/15/2021 15:25:25, Utc
TimeZoneInfo.Local: (UTC+08:00) CST

But this is weird, when I use timedatectl set-local-rtc 0 --adjust-system-clock to set it back, this issue cannot be reproduced anymore.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 18 (9 by maintainers)

Most upvoted comments

@tarekgh

localNow: 10/16/2021 00:37:00, Local, utcNow: 10/15/2021 16:37:00, Utc
TimeZoneInfo.Local: (UTC+08:00) CST
Linux 5.11.0-34-generic #36~20.04.1-Ubuntu SMP Fri Aug 27 08:06:32 UTC 2021
.NET 5.0.10
.... Invariant:              True ....
Asia/Shanghai
localNow: 10/15/2021 16:37:23, Local, utcNow: 10/15/2021 16:37:23, Utc
TimeZoneInfo.Local: (UTC) Coordinated Universal Time
Linux 5.11.0-34-generic #36~20.04.1-Ubuntu SMP Fri Aug 27 08:06:32 UTC 2021
.NET 6.0.0-rc.2.21480.5
.... Invariant:              True ....
UTC

Then I changed the timezone:

localNow: 10/15/2021 09:41:39, Local, utcNow: 10/15/2021 16:41:39, Utc
TimeZoneInfo.Local: (UTC-08:00) PST
Linux 5.11.0-34-generic #36~20.04.1-Ubuntu SMP Fri Aug 27 08:06:32 UTC 2021
.NET 5.0.10
.... Invariant:              True ....
America/Los_Angeles
localNow: 10/15/2021 16:42:31, Local, utcNow: 10/15/2021 16:42:31, Utc
TimeZoneInfo.Local: (UTC) Coordinated Universal Time
Linux 5.11.0-34-generic #36~20.04.1-Ubuntu SMP Fri Aug 27 08:06:32 UTC 2021
.NET 6.0.0-rc.2.21480.5
.... Invariant:              True ....
UTC

@ivan7wl Can you execute following commands and see what are being printed in your environment?

echo $TZ
echo $TZDIR
ls -l /etc/localtime
date

Since .NET reads time zone information from /etc/localtime and $TZDIR/$TZ, this might be an issue related to your environment.