it-source

현재 사용자 표준시를 c#로 가져오는 방법

criticalcode 2023. 8. 4. 23:09
반응형

현재 사용자 표준시를 c#로 가져오는 방법

나는 MVC3에서 애플리케이션을 구축하고 있는데 사용자가 내 사이트에 들어오면 그 사용자의 시간대를 알고 싶습니다.자바스크립트가 아닌 c#에서 어떻게 하는지 알고 싶습니다.

이미 언급했듯이, 당신은 당신의 고객이 당신의 ASP에게 말해야 합니다.네트워크 서버가 어느 시간대에 있는지에 대한 세부 정보입니다.

여기 예가 있어요.

Angular 컨트롤러는 SQL Server 데이터베이스의 레코드 목록을 JSON 형식으로 로드합니다.문제는,DateTime이 레코드의 값은 UTC 시간대에 있으며 사용자에게 로컬 시간대의 날짜/시간을 표시하려고 합니다.

자바스크립트 "JavaScript"를 )를 합니다.getTimezoneOffset()함수를 호출한 다음 이 값을 호출하려는 JSON 서비스의 URL에 추가합니다.

$scope.loadSomeDatabaseRecords = function () {

    var d = new Date()
    var timezoneOffset = d.getTimezoneOffset();

    return $http({
        url: '/JSON/LoadSomeJSONRecords.aspx?timezoneOffset=' + timezoneOffset,
        method: 'GET',
        async: true,
        cache: false,
        headers: { 'Accept': 'application/json', 'Pragma': 'no-cache' }
    }).success(function (data) {
        $scope.listScheduleLog = data.Results;
    });
}

의 ASP00 ASP에서. 코드, 넷코드, ▁the다니를 합니다.timezoneOffset매개 변수...

int timezoneOffset = 0;

string timezoneStr = Request["timezoneOffset"];
if (!string.IsNullOrEmpty(timezoneStr))
    int.TryParse(timezoneStr, out timezoneOffset);

LoadDatabaseRecords(timezoneOffset);

데이터베이스에서 레코드를 로드하는 내 기능에 전달합니다.

C#로 부르고 싶어서 좀 지저분하네요.FromUTCData데이터베이스의 각 레코드에서 작동하지만 LINQ에서 SQL까지는 원시 SQL을 C# 함수와 결합할 수 없습니다.

은 먼저을 해책은먼기결읽다은기반음시록것오다입니적간프는용하을에 적용하는 것입니다.DateTime각 레코드의 필드

public var LoadDatabaseRecords(int timezoneOffset)
{
    MyDatabaseDataContext dc = new MyDatabaseDataContext();

    List<MyDatabaseRecords> ListOfRecords = dc.MyDatabaseRecords.ToList();

    var results = (from OneRecord in ListOfRecords
           select new
           {
               ID = OneRecord.Log_ID,
               Message = OneRecord.Log_Message,
               StartTime =  FromUTCData(OneRecord.Log_Start_Time, timezoneOffset),
               EndTime = FromUTCData(OneRecord.Log_End_Time, timezoneOffset)
           }).ToList();

    return results;
}

public static DateTime? FromUTCData(DateTime? dt, int timezoneOffset)
{
    //  Convert a DateTime (which might be null) from UTC timezone
    //  into the user's timezone. 
    if (dt == null)
        return null;

    DateTime newDate = dt.Value - new TimeSpan(timezoneOffset / 60, timezoneOffset % 60, 0);
    return newDate;
}

하지만 그것은 잘 작동하며, 이 코드는 세계의 다른 지역의 사용자들에게 날짜/시간을 표시하기 위해 웹 서비스를 작성할 때 정말 유용합니다.

지금 저는 취리히 시간으로 오전 11시에 이 기사를 쓰고 있습니다만, 로스앤젤레스에서 기사를 읽고 있다면 제가 새벽 2시(현지 시간)에 편집한 것을 알 수 있을 것입니다.이와 같은 코드를 사용하면 웹 페이지가 웹 사이트의 국제 사용자에게 적합한 날짜 시간을 표시하도록 할 수 있습니다.

휴.

이게 도움이 되길 바랍니다.

이것은 사용자 IP 주소를 통해 가정하거나 사용자가 프로파일의 어떤 형태로든 설정하도록 하지 않는 한 서버 측에서 가능하지 않습니다.자바스크립트를 통해 고객들의 시간을 알 수 있습니다.

JavaScript 솔루션은 다음을 참조하십시오.JavaScript에서 클라이언트의 표준 시간대 가져오기

클라이언트 측 및 서버 측 기술을 모두 사용해야 합니다.

클라이언트 측:
(하나 선택)

  • 이 기능은 대부분의 최신 브라우저에서 작동합니다.

    Intl.DateTimeFormat().resolvedOptions().timeZone
    
  • 또한 jsTimeZoneDetect의jstz.determine()또는 모멘트-시간대의moment.tz.guess()이 라이브러리들은 일반적으로 오래된 응용 프로그램에서만 사용되지만 오래된 브라우저를 위한 기능.

둘 중 하나의 결과는 다음과 같은 IANA 표준 시간대 식별자가 될 것입니다.America/New_York원하는 방법으로 서버에 결과를 전송합니다.

서버 측:
(하나 선택)

  • 사용.TimeZoneInfo(모든 OS에서 NET 6+ 또는 Windows가 아닌 시스템에서만 사용 가능):

    TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
    
  • 모든 OS에서 TimeZone Converter 사용:

    TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("America/New_York");
    
  • 모든 OS에서 NodaTime 사용:

    DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"];
    

저도 같은 문제가 생겼는데, 안타깝게도 서버가 클라이언트 시간대를 알 수 있는 방법이 없습니다.당신이 원한다면, Ajax를 호출하는 동안 클라이언트 시간대를 헤더로 보낼 수 있습니다.

헤더 추가에 대한 자세한 정보가 필요한 경우 이 게시물은 요청할 헤더를 추가하는 방법에 도움이 될 수 있습니다: js 또는 jQuery를 사용하여 에이잭스 요청에 사용자 지정 HTTP 헤더를 추가하려면 어떻게 해야 합니까?

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

매번 헤더를 추가하고 싶지 않다면 쿠키가 모든 httpRequest와 함께 전송되기 때문에 쿠키를 설정하는 것을 생각할 수 있습니다. 쿠키를 처리하여 서버 측에서 클라이언트 표준 시간대를 가져올 수 있습니다. 하지만 쿠키를 추가하는 것은 그들이 모든 httpRequest와 동일한 이유로 선호하지 않습니다.감사해요.

Dot Net 버전 3.5 이상의 경우 다음을 사용할 수 있습니다.

TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);

그러나 버전 3.5 이전의 DotNet의 경우 다음 방법을 통해 수동으로 처리할 수 있습니다.

먼저 클라이언트에서 오프셋을 가져와 쿠키에 저장합니다.

function setTimezoneCookie(){
 
var timezone_cookie = "timezoneoffset";

// if the timezone cookie does not exist 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();
    }
}

}

그런 다음 백엔드 코드에서 쿠키를 사용할 수 있습니다.

   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();
}

사용자가 자바스크립트 이외의 솔루션에 대해 질문한 것은 알지만, 제가 생각해낸 자바스크립트 솔루션을 올리고 싶었습니다.일부 js 라이브러리(jsTimezoneDetect, momentjs)를 찾았지만 출력이 IANA 코드여서 C#에서 TimeZoneInfo 개체를 가져오는 데 도움이 되지 않는 것 같습니다.저는 jsTimezoneDetect에서 아이디어를 빌렸습니다.자바스크립트에서는 BaseUtcOffset과 DST의 첫날을 받아서 서버로 보냅니다.그런 다음 서버는 이 개체를 TimeZoneInfo 개체로 변환합니다.

현재로서는 클라이언트 표준시가 "태평양 표준시(미국)" 또는 "바하 캘리포니아"로 선택되어 있는지 여부에 상관하지 않습니다. 둘 중 하나가 정확한 시간 변환을 생성합니다(제 생각).일치하는 항목이 여러 개 있는 경우에는 현재 처음 찾은 TimeZoneInfo 일치 항목만 선택합니다.

그런 다음 UTC 날짜를 데이터베이스에서 로컬 시간으로 변환할 수 있습니다.

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

자바스크립트

// 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];
    }

클라이언트에서 서버로 이 정보를 가져올 수 있습니다(모든 웹 API 호출).

var timezoneOffset = new Date().getTimezoneOffset();

의도로으의 timezoneoffset당신이 같은 것을 달성할 수 있는 세부사항.여기서는 서버 측에서 UTC 날짜 시간을 클라이언트 로컬 날짜 시간으로 변환했습니다.

DateTime clientDateTime = DateTime.UtcNow - new TimeSpan(timezoneOffset / 60, timezoneOffset % 60, 0);

코드 예제를 보려면 클릭하십시오.

이 asp.net c# 솔루션을 살펴보십시오.

TimeZoneInfo mytzone = TimeZoneInfo.Local;
System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_TIMEZONE"] ;

언급URL : https://stackoverflow.com/questions/8194016/how-to-get-current-user-timezone-in-c-sharp

반응형