satyanarayana
satyanarayana

Reputation: 379

Get local time for a user

I have an application in VC++ which is used by different users in different timezones. I have to convert this logic to C# now. I am struck up with the dateformats respective to his/her timezone.

I will have the offset for each user and I am checking the daylight saving condition as follows:

if (TimeZoneInfo.Local.IsDaylightSavingTime(DateTime.Now) && useroffset!=0)
                    {
                        useroffset += 1;
                    }

Now my VC++ code is using the methods

                cdtDate = CComDATE(currentdate);
                cdtDate += CComSpan(0, useroffset, 0, 0);

May I know how to convert this to C#. Please guide me if there are any other ways to do it.

Upvotes: 0

Views: 784

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1502096

I will have the offset for each user

That's broken to start with. You can't have an offset for each user, because offsets change over time - and they don't all change at the same time. Your current code assumes that all users will change into DST at the same time as the server's local time zone. Different time zones change on different schedules, and some don't observe DST at all. (You also seem to be assuming that if the user's offset is 0, then they don't observe DST, which isn't correct for me - I'm sitting in the Europe/London time zone, which is currently UTC+0, but will move to UTC+1 on March 30th 2014.)

You should have a time zone ID for the user instead. Then you can use:

TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(userZoneId);
DateTime userLocalNow = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, zone);

As a massive plug, you might also want to consider using my Noda Time library, which supports both TimeZoneInfo (BCL) time zones, and the TZDB/IANA time zones which pretty much all systems other than Windows use. It also avoids some of the nasty design decisions of DateTime.

In Noda Time, the code would look like this:

DateTimeZoneProvider provider = DateTimeZoneProviders.Tzdb; // Or Bcl
ZonedDateTime userNow = clock.Now.InZone(provider[userZoneId]);

(Where clock is of type IClock, which gives greater testability too...)

Upvotes: 1

Related Questions