-3

It seems like in C# it is not possible to set the timezone for an application, so I want to change DateTime.Now to my timezone on a machine that runs on UTC which can not be changed. I want to use the System namespace to hide DateTime.Now because then I can not make the mistake of using the wrong DateTime.Now because it would be hidden. This is what I want to achieve:

namespace System
{
    public static class DateTime
    {
        public new static DateTime Now => System.DateTime.UtcNow.AddHours(1);
    }
}

But it does not work because of:

The type 'DateTime in '...DateTime.cs' conflicts with the imported type 'DateTime' in 'System.Runtime.'

Is there any way to do something like this?

Edit: I want to know if it is possible to "override" System.DateTime and if yes, how to do this.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Michael Santos
  • 466
  • 7
  • 15
  • 1
    `It seems like in C# it is not possible to set the timezone for a Application` please elaborate. You possibly build your reasoning on a false premise. – Wiktor Zychla Nov 30 '19 at 21:34
  • I found this : https://stackoverflow.com/a/33869808/8529170 ,but this is not for the whole applicaiton with many threads just for the current thread. But i found only people writing that it is not possible fro the complete application. – Michael Santos Nov 30 '19 at 21:43
  • Does this answer your question? [What's a good way to overwrite DateTime.Now during testing?](https://stackoverflow.com/questions/43711/whats-a-good-way-to-overwrite-datetime-now-during-testing) – FaFryk Nov 30 '19 at 21:45
  • no i want to "override" System.DateTime.Now, the title of the question is right but none of the answers do what is asked by your linked question oder does what i want – Michael Santos Nov 30 '19 at 21:49
  • @MichaelSantos I think you're trying to solve the wrong problem. If you need some aspect of your application to be portable across timezones, then you should always use UTC time. You can convert from UTC time to local time as necessary. If you want to avoid using the wrong time method, then **write unit tests** for all of your date-handling code. – Daniel Mann Nov 30 '19 at 22:01

1 Answers1

3

Instead of "overriding" System.DateTime, wrap it with own class and use it everywhere

public class ApplicationTime
{
    private readonly int _offset;

    public DateTime Now => System.DateTime.UtcNow.AddHours(offset);

    public ApplicationTime(int hoursOffset) => _offset = hoursOffset;
}

Usage

var applicationTime = new ApplicationTime(1);

var delivery = new Delivery
{
    CreatedAt = applicationTime.Now
};

Technically is possible to "override" DateTime.Now.
But I would not suggest to use it in actual application, especially where your friends developers reading and using your code ;)

This can be done if you are using default location for using directives, which is on top of the file and you are not using full name of the DateTime type. (not this: System.DateTime.Now)

using System;

namespace Business
{
    public class Dispatching
    {
        public string Send(string delivery)
        {
            return $"Delivery '{delivery}' sent at {DateTime.Now:dd-MM-yyyy HH:mm}";
        }
    }
}

Because using DateTime; is located outside of namespace, compiler will look for the type DateTime from Business namespace first and if not found will check imported namespaces.
So we can take advantage of this and introduce our own implementation of DateTime inside Business namespace.

namespace Business
{
    public class DateTime
    {
        public static System.DateTime Now => System.DateTime.UtcNow.AddHours(1);
    }
}

Then

var output = new Dispatching.Send("to destination");
Console.WriteLine(output);

// Delivery 'to destination' sent at 01-12-2019 03:10:49
// UTC time + 1 hour

If we put using directive inside namespace, our "overriding" will be ignored.

namespace Business
{
    using System;

    public class Dispatching
    {
        public string Send(string delivery)
        {
            return $"Delivery '{delivery}' sent at {DateTime.Now:dd-MM-yyyy HH:mm}";
        }
    }
}
Fabio
  • 31,528
  • 4
  • 33
  • 72
  • "overriding" System.DateTime is exactly what i want, i want to know if it is possible and if yes how – Michael Santos Nov 30 '19 at 21:50
  • yes, it is possible, but with some constraints, which produce more problems than benefits – Fabio Nov 30 '19 at 21:56
  • @MichaelSantos, check updated, answer, but I do not suggest to use this approach, this just abusing compiler lookup logic and make your colleagues work/life difficult. – Fabio Dec 01 '19 at 02:28