How to get current user timezone in c#

2019-01-04 12:22发布

I am building an application in MVC3 and when a user comes into my site I want to know that user's timezone. I want to know how to do this in c# not in javaScript?

7条回答
叼着烟拽天下
2楼-- · 2019-01-04 12:44

You can try using below snipet...

var timeZone = $"{TimeZoneInfo.Local.StandardName} : {TimeZoneInfo.Local.DisplayName}";

Thanks

查看更多
神经病院院长
3楼-- · 2019-01-04 12:47

For Dot Net version 3.5 and higher you can use :

TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);

but for Dot Net Under version 3.5 you can handle it manually via this way :

first get Offset from client and store it in cookie

function setTimezoneCookie(){

var timezone_cookie = "timezoneoffset";

// if the timezone cookie not exists create one.
if (!$.cookie(timezone_cookie)) { 

    // check if the browser supports cookie
    var test_cookie = 'test cookie';
    $.cookie(test_cookie, true);

    // browser supports cookie
    if ($.cookie(test_cookie)) { 

        // delete the test cookie
        $.cookie(test_cookie, null);

        // create a new cookie 
        $.cookie(timezone_cookie, new Date().getTimezoneOffset());

        // re-load the page
        location.reload(); 
    }
}
// if the current timezone and the one stored in cookie are different
// then store the new timezone in the cookie and refresh the page.
else {         

    var storedOffset = parseInt($.cookie(timezone_cookie));
    var currentOffset = new Date().getTimezoneOffset();

    // user may have changed the timezone
    if (storedOffset !== currentOffset) { 
        $.cookie(timezone_cookie, new Date().getTimezoneOffset());
        location.reload();
    }
}

}

after that you can use cookie in backend code like that :

   public static string ToClientTime(this DateTime dt)
{
    // read the value from session
    var timeOffSet = HttpContext.Current.Session["timezoneoffset"];  

    if (timeOffSet != null) 
    {
        var offset = int.Parse(timeOffSet.ToString());
        dt = dt.AddMinutes(-1 * offset);

        return dt.ToString();
    }

    // if there is no offset in session return the datetime in server timezone
    return dt.ToLocalTime().ToString();
}
查看更多
Animai°情兽
4楼-- · 2019-01-04 12:54

I know the user asked about a non-javascript solution, but I wanted to post a javascript solution that I came up with. I found some js libraries (jsTimezoneDetect, momentjs), but their output was an IANA code, which didn't seem to help me with getting a TimeZoneInfo object in C#. I borrowed ideas from jsTimezoneDetect. In javascript, I get the BaseUtcOffset and the first day of DST and send to server. The server then converts this to a TimeZoneInfo object.

Right now I don't care if the client Time Zone is chosen as "Pacific Time (US)" or "Baja California" for example, as either will create the correct time conversions (I think). If I find multiple matches, I currently just pick the first found TimeZoneInfo match.

I can then convert my UTC dates from the database to local time:

DateTime clientDate = TimeZoneInfo.ConvertTimeFromUtc(utcDate, timeZoneInfo);

Javascript

// Time zone.  Sets two form values:
// tzBaseUtcOffset: minutes from UTC (non-DST)
// tzDstDayOffset: number of days from 1/1/2016 until first day of DST ; 0 = no DST
var form = document.forms[0];
var janOffset = -new Date(2016, 0, 1).getTimezoneOffset();      // Jan
var julOffset = -new Date(2016, 6, 1).getTimezoneOffset();      // Jul
var baseUtcOffset = Math.min(janOffset, julOffset);             // non DST offset (winter offset)
form.elements["tzBaseUtcOffset"].value = baseUtcOffset;
// Find first day of DST (from 1/1/2016)
var dstDayOffset = 0;
if (janOffset != julOffset) {
    var startDay = janOffset > baseUtcOffset ? 180 : 0; // if southern hemisphere, start 180 days into year
    for (var day = startDay; day < 365; day++) if (-new Date(2016, 0, day + 1, 12).getTimezoneOffset() > baseUtcOffset) { dstDayOffset = day; break; }    // noon
}
form.elements["tzDstDayOffset"].value = dstDayOffset;

C#

    private TimeZoneInfo GetTimeZoneInfo(int baseUtcOffset, int dstDayOffset) {

        // Converts client/browser data to TimeZoneInfo
        // baseUtcOffset: minutes from UTC (non-DST)
        // dstDayOffset: number of days from 1/1/2016 until first day of DST ; 0 = no DST
        // Returns first zone info that matches input, or server zone if none found

        List<TimeZoneInfo> zoneInfoArray = new List<TimeZoneInfo>();    // hold multiple matches
        TimeSpan timeSpan = new TimeSpan(baseUtcOffset / 60, baseUtcOffset % 60, 0);
        bool supportsDst = dstDayOffset != 0;
        foreach (TimeZoneInfo zoneInfo in TimeZoneInfo.GetSystemTimeZones()) {
            if (zoneInfo.BaseUtcOffset.Equals(timeSpan) && zoneInfo.SupportsDaylightSavingTime == supportsDst) {
                if (!supportsDst) zoneInfoArray.Add(zoneInfo);
                else {
                    // Has DST. Find first day of DST and test for match with sent value. Day = day offset into year
                    int foundDay = 0;
                    DateTime janDate = new DateTime(2016, 1, 1, 12, 0, 0);  // noon
                    int startDay = zoneInfo.IsDaylightSavingTime(janDate) ? 180 : 0;    // if southern hemsphere, start 180 days into year
                    for (int day = startDay; day < 365; day++) if (zoneInfo.IsDaylightSavingTime(janDate.AddDays(day))) { foundDay = day; break; }
                    if (foundDay == dstDayOffset) zoneInfoArray.Add(zoneInfo);
                }
            }
        }
        if (zoneInfoArray.Count == 0) return TimeZoneInfo.Local;
        else return zoneInfoArray[0];
    }
查看更多
啃猪蹄的小仙女
5楼-- · 2019-01-04 12:56

This isn't possible server side unless you assume it via the users ip address or get the user to set it in some form of a profile. You could get the clients time via javascript.

See here for the javacript solution: Getting the client's timezone in JavaScript

查看更多
淡お忘
6楼-- · 2019-01-04 12:59
System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_TIMEZONE"] ;
查看更多
Juvenile、少年°
7楼-- · 2019-01-04 13:05

I got the same issue , Unfortunately there is no way for the server to know the client timezone . If you want you can send client timezone as header while making ajax call .

In-case if you want more info on adding the header this post may help how to add header to request : How can I add a custom HTTP header to ajax request with js or jQuery?

new Date().getTimezoneOffset();//gets the timezone offset

If you don't want to add header every time , you can think of setting a cookie since cookie is sent with all httpRequest you can process the cookie to get client timezone on server side . But i don't prefer adding cookies , for the same reason they sent with all http requests. Thanks.

查看更多
登录 后发表回答