dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.17k stars 4.72k forks source link

Run the application with a different time zone. #42241

Open EvgenyPrikhodko opened 4 years ago

EvgenyPrikhodko commented 4 years ago

Run application in a different time zone Problems:

  1. There is no source code.
  2. The project is large, written previously to rewrite using, for example, TimeZoneInfo great refactoring.
  3. This is especially problematic when applications need to be run from a hosting provider (azure, amazone, etc.).
  4. When the developer doesn't know the server timezone.

For example like this: dotnet myapp.dll --timezone "Morocco Standard Time"

Optional: This discussion was discussed here

Dotnet-GitSync-Bot commented 4 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

danmoseley commented 4 years ago

@tarekgh

Gnbrkm41 commented 4 years ago

How hard is it to do timedatectl set-timezone Africa/Casablanca (*nix) or Set-TimeZone -Id "Morocco Standard Time" (Windows) before running the app, or what restricts you from doing that? Why do you want the OS Timezone to be different from the app's timezone? What about possible discrepancies between the app itself and dependencies of the app that acquire timezone / time data from other sources - e.g. native libraries that directly call into the OS?

I'm not exactly sure why this feature is required and how much value this holds, other than being (what looks to me) a hacky workaround for a specific problem that I'm unsure if it is common. Could you perhaps elaborate a bit more about your scenario?

EvgenyPrikhodko commented 4 years ago

How hard is it to do timedatectl set-timezone Africa/Casablanca (*nix) or Set-TimeZone -Id "Morocco Standard Time" (Windows) before running the app, or what restricts you from doing that? >

Not difficult. but in my version does not solve the problem, for example, I have other applications on the same server that may live in a different time zone

Why do you want the OS Timezone to be different from the app's timezone? >

It is very simple, take an example, hosting does not always have access to the OS, or the server uses UTC, and the application should, for example, be in utc + 3.

What about possible discrepancies between the app itself and dependencies of the app that acquire timezone / time data from other sources - e.g. native libraries that directly call into the OS?

It is understandable here, if the application uses other people's native libraries, I agree, in this case you need to solve the issue differently. Not my case

I'm not exactly sure why this feature is required and how much value this holds, other than being (what looks to me) a hacky workaround for a specific problem that I'm unsure if it is common. Could you perhaps elaborate a bit more about your scenario?

It's very simple, we have 3 web servers running asp.net Core. I needed to launch another application, but it turned out that a different time zone was needed. Moreover, this application will be launched in 5 instances in 5 different time zones. That would not buy 5 servers, this option will save money and time. When to use a specific time zone within the same application.

ghost commented 4 years ago

Tagging subscribers to this area: @tarekgh, @safern, @krwq See info in area-owners.md if you want to be subscribed.

Clockwork-Muse commented 4 years ago

Moreover, this application will be launched in 5 instances in 5 different time zones. That would not buy 5 servers, this option will save money and time.

If you can use Docker, you can set the timezone for the container. However....

It is very simple, take an example, hosting does not always have access to the OS, or the server uses UTC, and the application should, for example, be in utc + 3.

It's not going to help in your case (since you don't have the original source to modify), but generally the server/os/process timezone should be completely irrelevant. You want some way for your application to retrieve/use an entity timezone - it figures out what timezone it needs based on what entity it's processing, and uses that. Potentially, that means that you'd only launch one instance of the application (and definitely makes your server config easier).

Some legacy applications were definitely written assuming a specific server timezone, but modern applications should not be written that way.

PathogenDavid commented 3 years ago

It's worth noting that the runtime already supports the TZ environment variable on Linux:

image

The value of TZ can basically be any file under /usr/share/zoneinfo. (Or an absolute path to a custom timezone file.)

This functionality is implemented by TimeZoneInfo.TryGetLocalTzFile.

tarekgh commented 3 years ago

@PathogenDavid what is your scenario you want to use this for?

PathogenDavid commented 3 years ago

@tarekgh I have 0 use for this feature, I just stumbled upon the discussion and thought I'd mention TZ since it's less hacky than the reflection method as long as you don't need Windows support. (Which was seemingly the case for @EvgenyPrikhodko)

EvgenyPrikhodko commented 3 years ago

@tarekgh I have 0 use for this feature, I just stumbled upon the discussion and thought I'd mention TZ since it's less hacky than the reflection method as long as you don't need Windows support. (Which was seemingly the case for @EvgenyPrikhodko)

Thanks, but your solution doesn't work for me.

PathogenDavid commented 3 years ago

@EvgenyPrikhodko Not sure what to tell you, works fine for me on WSL.

EvgenyPrikhodko commented 3 years ago

@EvgenyPrikhodko Not sure what to tell you, works fine for me on WSL.

Thank you, we know this option.

betmix-matt commented 2 years ago

It's worth noting that the runtime already supports the TZ environment variable on Linux:

image

The value of TZ can basically be any file under /usr/share/zoneinfo. (Or an absolute path to a custom timezone file.)

This functionality is implemented by TimeZoneInfo.TryGetLocalTzFile.

Instead of adding a new argument to dotnet run, why not just make Windows consistent with Linux so that if the TZ environment variable is set in Windows, dotnet automatically uses that to determine the system timezone?

tarekgh commented 2 years ago

Instead of adding a new argument to dotnet run, why not just make Windows consistent with Linux so that if the TZ environment variable is set in Windows, dotnet automatically uses that to determine the system timezone?

This is a clever idea. The only concern with that setting such environment variable is going to affect other applications running on the same machine if the environment variable is set per user or machine. On Linux is ok as this is documented behavior for the OS. But Windows doesn't support that and can be a surprise for some applications. Maybe the best here is to do that with a config switch?

betmix-matt commented 2 years ago

I guess it is kinda a major change as it could technically be a breaking change. It would be really nice if you didn't have to specify a command line argument to make this work though. I hate that for every OS except windows, TZ sets the timezone. Why does windows have to be so difficult?

tarekgh commented 2 years ago

It would be really nice if you didn't have to specify a command line argument to make this work though.

agree.

Why does windows have to be so difficult?

Did you request that from Windows before? :-)

yunfandev commented 2 years ago

@roji Hi roji, When I upgrade Npgsql to 6.x, is there any way I can set the timezone to UTC when I debug the dotnet program using Visual Studio 2022 on Windows, and my computer's time zone is UTC+8. 😂😂😂

Or I have to use the following code:

#if DEBUG
    AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
#endif
roji commented 2 years ago

@yunfandev in Npgsql 6.x, what your machine timezone is has no bearing on what Npgsql does; unless you enable EnableLegacyTimestampBehavior, Npgsql no longer performs any implicit timezone conversions based on the (.NET's) machine timezone.

I'd suggest opening an issue on https://github.com/npgsql/npgsql or https://github.com/efcore.pg/npgsql, and providing more context (with code samples) on what your exact problem is. That's unlikely to be related to this issue.

yunfandev commented 2 years ago

@yunfandev in Npgsql 6.x, what your machine timezone is has no bearing on what Npgsql does; unless you enable EnableLegacyTimestampBehavior, Npgsql no longer performs any implicit timezone conversions based on the (.NET's) machine timezone.

I'd suggest opening an issue on https://github.com/npgsql/npgsql or https://github.com/efcore.pg/npgsql, and providing more context (with code samples) on what your exact problem is. That's unlikely to be related to this issue.

@roji Because we have a lot of DateTimeOffset.Now and DateTimeOffset.FromUnixTimeSeconds in our code, I want to directly adjust the time zone of the runtime to Utc😅, so that the offset of the default DatetimeOffset is all 0. It's easy to set the timezone when running in a container but not when debugging on Windows. Or I should adjust the time zone of DateTimeOffset in the code by myself, instead of simply solving the problem by adjusting the time zone

roji commented 2 years ago

Or I should adjust the time zone of DateTimeOffset in the code by myself, instead of simply solving the problem by adjusting the time zone

Yes. If what you're looking for is a UTC timestamp, it's much better to adjust your code to call DateTimeOffset.UtcNow instead of DateTimeOffset.Now. This is the correct way to address it, and would make the actual intent and meaning much clearer in your source code.

yunfandev commented 2 years ago

Or I should adjust the time zone of DateTimeOffset in the code by myself, instead of simply solving the problem by adjusting the time zone

Yes. If what you're looking for is a UTC timestamp, it's much better to adjust your code to call DateTimeOffset.UtcNow instead of DateTimeOffset.Now. This is the correct way to address it, and would make the actual intent and meaning much clearer in your source code.

Thanks ❤️