웹 서버가 웹 페이지 내에서 사용자의 시간대를 결정할 수있는 표준 방법이 있습니까?
아마도 HTTP 헤더 또는 user-agent
문자열의 일부 입니까?
웹 서버가 웹 페이지 내에서 사용자의 시간대를 결정할 수있는 표준 방법이 있습니까?
아마도 HTTP 헤더 또는 user-agent
문자열의 일부 입니까?
답변:
-new Date().getTimezoneOffset()/60;
이 방법 getTimezoneOffset()
은 GMT에서 시간을 빼고 분을 반환합니다. 따라서 GMT-8에 거주하면 480을 반환합니다.
이것을 시간으로 나누려면 60으로 나눕니다. 또한 부호는 필요한 것과 반대입니다. 즉 표준 시간대의 GMT 오프셋이 아니라 표준 시간대의 GMT 오프셋을 계산합니다. 이 문제를 해결하려면 -1을 곱하면됩니다.
또한 w3school 은 다음과 같이 말합니다.
일광 절약 시간제를 사용하기 때문에 반환 값이 상수가 아닙니다.
>>> date.toTimeString() "15:46:04 GMT+1200 (New Zealand Standard Time)"
내가 본 시간대를 결정하는 가장 인기있는 (== 표준?) 방법은 단순히 사용자에게 묻는 것입니다. 웹 사이트에 가입이 필요한 경우 사용자의 프로필 데이터에 저장 될 수 있습니다. 익명 사용자의 경우 날짜는 UTC 또는 GMT 등으로 표시 될 수 있습니다.
나는 스마트 알렉이 되려고 노력하고 있지 않다. 때로는 일부 문제가 프로그래밍 컨텍스트 외부에서 더 나은 솔루션을 가지고 있다는 것입니다.
HTTP 스펙에 포함하도록 제안되었지만 클라이언트 시간대를 지금까지보고 할 HTTP 헤더는 없습니다.
그것이 있다면 클라이언트 측 JavaScript를 사용하여 시간대를 가져 와서 Ajax 또는 다른 것을 사용하여 서버에 제출하려고합니다.
JavaScript는 클라이언트의 현지 시간을 얻는 가장 쉬운 방법입니다. XMLHttpRequest 를 사용 하여 로컬 시간을 다시 보내도록 제안하고, 실패하면 IP 주소를 기반으로 감지 된 시간대로 폴백합니다.
지리적 위치에 관해서 는 여러 프로젝트에서 MaxMind GeoIP 를 사용 했으며 시간대 데이터를 제공하는지 확실하지 않지만 잘 작동합니다. 귀하가 비용을 지불하는 서비스이며 데이터베이스에 대한 월별 업데이트를 제공합니다. 여러 웹 언어로 래퍼를 제공합니다.
먼저 JavaScript에서 시간대 감지가 불완전하다는 것을 이해하십시오. 객체 의 인스턴스를 사용하여 특정 날짜 및 시간에 대한 현지 시간대 오프셋 을 가져올 수 있지만 이는 같은 전체 IANA 시간대 와 동일하지 않습니다 .getTimezoneOffset
Date
America/Los_Angeles
그래도 작동 할 수있는 몇 가지 옵션이 있습니다.
const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(tzid);
결과는 코드가 실행중인 컴퓨터의 IANA 시간대 설정이 포함 된 문자열입니다.
지원되는 환경은 Intl 호환성 표에 나열 되어 있습니다. 확장 DateTimeFormat
섹션 및 명명 된이 기능을보고 resolvedOptions().timeZone defaults to the host environment
.
Luxon 과 같은 일부 라이브러리 는이 API를 사용하여와 같은 기능을 통해 시간대를 결정합니다 luxon.Settings.defaultZoneName
.
Intl
사용 가능한 경우 먼저 API를 시도하여 사용할 수 있으며, 사용 가능하지 않은 경우 결과를 사용하여 내부 데이터 세트에서 적절한 시간대를 선택하여 여러 시점에서 오브젝트 의 getTimezoneOffset
기능을 조사합니다 Date
.두 jsTimezoneDetect 및 순간 시간대는 이 기능을 가지고있다.
// using jsTimeZoneDetect
var tzid = jstz.determine().name();
// using moment-timezone
var tzid = moment.tz.guess();
두 경우 모두 결과는 추측으로 만 생각할 수 있습니다. 대부분의 경우 추측이 정확할 수 있지만 전부는 아닙니다.
또한이 라이브러리는 많은 오래된 JavaScript 구현이 현지 시간대 의 현재 일광 절약 시간제 규칙 만 알고 있다는 사실을 막기 위해 정기적으로 업데이트해야 합니다. 자세한 내용은 여기를 참조하십시오.
궁극적으로 더 나은 방법은 실제로 사용자에게 시간대를 요청하는 것입니다. 변경할 수있는 설정을 제공하십시오. 위의 옵션 중 하나를 사용하여 기본 설정 을 선택할 수 있지만 앱에서 해당 설정을 벗어날 수는 없습니다.
사용자 컴퓨터의 시간대 설정에 전혀 의존 하지 않는 완전히 다른 접근법도 있습니다 . 대신 위도 및 경도 좌표를 수집 할 수있는 경우 다음 방법 중 하나를 사용하여 해당 좌표를 표준 시간대로 해결할 수 있습니다 . 이것은 모바일 장치에서 잘 작동합니다.
다음은 브라우저의 시간대를 결정하는 강력한 JavaScript 솔루션입니다.
>>> var timezone = jstz.determine();
>>> timezone.name();
"Europe/London"
https://bitbucket.org/pellepim/jstimezonedetect
부록 1 : 이제이 프로젝트는 GitHub에 있습니다 : https://github.com/pellepim/jstimezonedetect
더 완벽한 방법이 있습니다.
발췌는 다음과 같습니다.
function TimezoneDetect(){
var dtDate = new Date('1/1/' + (new Date()).getUTCFullYear());
var intOffset = 10000; //set initial offset high so it is adjusted on the first attempt
var intMonth;
var intHoursUtc;
var intHours;
var intDaysMultiplyBy;
// Go through each month to find the lowest offset to account for DST
for (intMonth=0;intMonth < 12;intMonth++){
//go to the next month
dtDate.setUTCMonth(dtDate.getUTCMonth() + 1);
// To ignore daylight saving time look for the lowest offset.
// Since, during DST, the clock moves forward, it'll be a bigger number.
if (intOffset > (dtDate.getTimezoneOffset() * (-1))){
intOffset = (dtDate.getTimezoneOffset() * (-1));
}
}
return intOffset;
}
JS에서 TZ 및 DST 가져 오기 (Way Back Machine을 통해)
Africa/Johannesburg
또는 Europe/Istanbul
. 시간대 태그 위키를 참조하십시오 .
Unkwntech의 접근 방식을 사용하여 jQuery와 PHP를 사용하여 함수를 작성했습니다. 이것은 테스트되고 작동합니다!
시간대를 변수로 사용하려는 PHP 페이지에서 페이지 상단 근처에 다음 코드 스 니펫을 배치하십시오.
<?php
session_start();
$timezone = $_SESSION['time'];
?>
이제 세션 변수 "time"을 읽을 것입니다.
동일한 페이지의 <head>에서 먼저 jQuery를 포함해야합니다.
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
또한 jQuery 아래의 <head>에서 다음을 붙여 넣으십시오.
<script type="text/javascript">
$(document).ready(function() {
if("<?php echo $timezone; ?>".length==0){
var visitortime = new Date();
var visitortimezone = "GMT " + -visitortime.getTimezoneOffset()/60;
$.ajax({
type: "GET",
url: "http://example.org/timezone.php",
data: 'time='+ visitortimezone,
success: function(){
location.reload();
}
});
}
});
</script>
눈치 채 셨을지도 모르지만 URL을 실제 도메인으로 변경해야합니다.
마지막 한가지. 당신은 아마도 heck timezone.php가 무엇인지 궁금 할 것입니다. 글쎄, 그것은 간단합니다 : ( timezone.php 라는 새 파일을 만들고 위의 URL로 가리 킵니다)
<?php
session_start();
$_SESSION['time'] = $_GET['time'];
?>
올바르게 작동하면 먼저 페이지를로드하고 JavaScript를 실행 한 다음 페이지를 다시로드합니다. 그러면 $ timezone 변수를 읽고 즐거움을 누릴 수 있습니다! 현재 UTC / GMT 표준 시간대 오프셋 (GMT -7) 또는 현재 시간대를 반환합니다.
jQuery를 사용 하여 AJAX 요청에서 표준 시간대 오프셋을 HTTP 헤더로 제출하려면
$.ajaxSetup({
beforeSend: function(xhr, settings) {
xhr.setRequestHeader("X-TZ-Offset", -new Date().getTimezoneOffset()/60);
}
});
http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/moment.tz.guess();
에서 사용하여 실제 시간대 이름을 얻는 것과 비슷한 작업을 수행 할 수도 있습니다 .
나는 여전히 시간대를 얻는 자세한 답변을 보지 못했습니다. IP 주소로 지오 코딩하거나 PHP (lol)를 사용하거나 오프셋을 잘못 추측 할 필요가 없습니다.
첫째, 시간대는 GMT와의 오프셋이 아닙니다. 시간 규칙이 현지 표준에 의해 설정되는 토지 영역입니다. 일부 국가에서는 일광 절약 시간제를 사용하며 다른 시간에 DST를 켤 것입니다. 일반적으로 현재 오프셋뿐만 아니라 실제 영역을 얻는 것이 중요합니다.
이 시간대를 저장하려는 경우 (예 : 사용자 환경 설정) 오프셋뿐만 아니라 해당 영역을 원합니다. 실시간 전환에는 별 문제가되지 않습니다.
이제 자바 스크립트로 시간대를 얻으려면 다음을 사용할 수 있습니다.
>> new Date().toTimeString();
"15:46:04 GMT+1200 (New Zealand Standard Time)"
//Use some regular expression to extract the time.
그러나 Olsen 형식의 시간대를 반환하는이 강력한 플러그인을 사용하는 것이 더 쉽다는 것을 알았습니다.
PHP date
기능을 사용하면 사이트가 위치한 서버의 날짜 시간을 얻을 수 있습니다. 사용자 시간을 얻는 유일한 방법은 JavaScript를 사용하는 것입니다.
그러나 사이트에 등록이 필요한 경우 사용자에게 필수 필드로 등록하도록 요청하는 것이 가장 좋습니다. 등록 페이지에 다양한 시간대를 나열하고 데이터베이스에 저장할 수 있습니다. 그런 다음 사용자가 사이트에 로그인하면 사용자가 선택한 시간대에 따라 해당 세션의 기본 시간대를 설정할 수 있습니다.
PHP 기능을 사용하여 특정 시간대를 설정할 수 있습니다 date_default_timezone_set
. 사용자의 지정된 시간대를 설정합니다.
기본적으로 사용자 시간대는 클라이언트쪽으로 이동하므로 JavaScript를 사용해야합니다.
다음은 PHP 및 JavaScript를 사용하여 사용자 시간대를 가져 오는 스크립트입니다.
<?php
#http://www.php.net/manual/en/timezones.php List of Time Zones
function showclienttime()
{
if(!isset($_COOKIE['GMT_bias']))
{
?>
<script type="text/javascript">
var Cookies = {};
Cookies.create = function (name, value, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
}
else {
var expires = "";
}
document.cookie = name + "=" + value + expires + "; path=/";
this[name] = value;
}
var now = new Date();
Cookies.create("GMT_bias",now.getTimezoneOffset(),1);
window.location = "<?php echo $_SERVER['PHP_SELF'];?>";
</script>
<?php
}
else {
$fct_clientbias = $_COOKIE['GMT_bias'];
}
$fct_servertimedata = gettimeofday();
$fct_servertime = $fct_servertimedata['sec'];
$fct_serverbias = $fct_servertimedata['minuteswest'];
$fct_totalbias = $fct_serverbias – $fct_clientbias;
$fct_totalbias = $fct_totalbias * 60;
$fct_clienttimestamp = $fct_servertime + $fct_totalbias;
$fct_time = time();
$fct_year = strftime("%Y", $fct_clienttimestamp);
$fct_month = strftime("%B", $fct_clienttimestamp);
$fct_day = strftime("%d", $fct_clienttimestamp);
$fct_hour = strftime("%I", $fct_clienttimestamp);
$fct_minute = strftime("%M", $fct_clienttimestamp);
$fct_second = strftime("%S", $fct_clienttimestamp);
$fct_am_pm = strftime("%p", $fct_clienttimestamp);
echo $fct_day.", ".$fct_month." ".$fct_year." ( ".$fct_hour.":".$fct_minute.":".$fct_second." ".$fct_am_pm." )";
}
showclienttime();
?>
그러나 내 관점에 따르면 프로젝트에 등록이 필수인지 사용자에게 묻는 것이 좋습니다.
자바 스크립트 :
function maketimus(timestampz)
{
var linktime = new Date(timestampz * 1000);
var linkday = linktime.getDate();
var freakingmonths = new Array();
freakingmonths[0] = "jan";
freakingmonths[1] = "feb";
freakingmonths[2] = "mar";
freakingmonths[3] = "apr";
freakingmonths[4] = "may";
freakingmonths[5] = "jun";
freakingmonths[6] = "jul";
freakingmonths[7] = "aug";
freakingmonths[8] = "sep";
freakingmonths[9] = "oct";
freakingmonths[10] = "nov";
freakingmonths[11] = "dec";
var linkmonthnum = linktime.getMonth();
var linkmonth = freakingmonths[linkmonthnum];
var linkyear = linktime.getFullYear();
var linkhour = linktime.getHours();
var linkminute = linktime.getMinutes();
if (linkminute < 10)
{
linkminute = "0" + linkminute;
}
var fomratedtime = linkday + linkmonth + linkyear + " " +
linkhour + ":" + linkminute + "h";
return fomratedtime;
}
이 기능에 시간을 Unix 타임 스탬프 형식으로 제공하십시오. JavaScript는 이미 사용자의 시간대를 알고 있습니다.
이처럼 :
PHP :
echo '<script type="text/javascript">
var eltimio = maketimus('.$unix_timestamp_ofshiz.');
document.write(eltimio);
</script><noscript>pls enable javascript</noscript>';
이것은 항상 사람이 자신의 컴퓨터 시계에 설정 한 시간대를 기준으로 시간을 정확하게 표시합니다. 아무에게도 물어볼 필요가 없으며 장소에 저장하십시오. 하느님 감사합니다!
다음 getTimezoneOffset
과 같이 JavaScript 함수를 사용하십시오 .
-new Date().getTimezoneOffset()/60;
모든 마법이
visitortime.getTimezoneOffset()
멋지다, 나는 그것에 대해 몰랐다. Internet Explorer 등에서 작동합니까? 거기에서 JavaScript를 사용하여 Ajax에 쿠키를 설정할 수 있습니다. 아마도 쿠키 루트를 직접 방문했을 것입니다.
사용자가 변경할 수 있도록해야합니다. 우리는 지오 로케이션 (maxmind를 통해)을 사용하여 얼마 전에이 작업을 수행하려고했지만 합리적으로 자주 잘못되었습니다. 그럴만한 가치가 없었기 때문에 사용자가 자신의 프로필에서 설정하도록하고 아직 설정하지 않았습니다.
다음은 ASP.NET (VB.NET, C #) 응용 프로그램에서 현지화 된 시간을 확인하고 사용하는 방법을 설명하는 문서 (소스 코드 포함)입니다.
간단히 말해서, 설명 된 접근 방식은 JavaScript getTimezoneOffset
쿠키 에 의존합니다. JavaScript 함수는 세션 쿠키에 저장되고 GMT와 로컬 시간 사이의 시간 값을 조정하기 위해 코드 숨김에서 사용되는 값을 리턴합니다. 좋은 점은 사용자가 시간대를 지정할 필요가 없다는 것입니다 (코드가 자동으로 수행함). 더 관련이 있지만 (이것이 기사에 링크 된 이유입니다) 제공되는 코드를 사용하면 실제로 사용하기가 쉽습니다. ASP.NET을 이해하는 한 논리를 PHP 및 다른 언어로 변환 할 수 있다고 생각합니다.
인증에 OpenID 를 사용하는 경우 Simple Registration Extension 은 인증 된 사용자의 문제를 해결합니다 (tz에서 숫자로 변환해야 함).
다른 옵션은 사용자 에이전트의 국가 환경 설정에서 시간대를 유추하는 것입니다. 이것은 다소 조잡한 방법이지만 (en-US에서는 작동하지 않음) 근사치가 좋습니다.
JavaScript와 PHP로 간단합니다 :
사용자가 자신의 내부 시계 및 / 또는 시간대를 망칠 수 있지만 오프셋을 얻기 위해 지금까지 찾은 가장 좋은 방법은 남아 있습니다 new Date().getTimezoneOffset();
. 비 침습적이며 두통을 유발하지 않으며 타사에 의존 할 필요가 없습니다.
유닉스 타임 스탬프를 저장하기위한 users
필드를 포함 하는 테이블이 있다고 가정 date_created int(13)
하자.
클라이언트를 가정하면 creates a new account
, 데이터가 수신되고 post
, 내가 필요 클라이언트의 유닉스 타임 스탬프가 아닌 서버와.insert/update
date_created column
삽입 / 업데이트시 timezoneOffset이 필요하므로 클라이언트가 양식을 제출할 때 추가 $ _POST 요소로 전달되므로 세션 및 / 또는 쿠키에 저장할 필요가 없으며 추가 서버 적중도 없습니다.
var off = (-new Date().getTimezoneOffset()/60).toString();//note the '-' in front which makes it return positive for negative offsets and negative for positive offsets
var tzo = off == '0' ? 'GMT' : off.indexOf('-') > -1 ? 'GMT'+off : 'GMT+'+off;
서버가 다음 tzo
과 같이 수신한다고 가정하십시오 $_POST['tzo']
.
$ts = new DateTime('now', new DateTimeZone($_POST['tzo']);
$user_time = $ts->format("F j, Y, g:i a");//will return the users current time in readable format, regardless of whether date_default_timezone() is set or not.
$user_timestamp = strtotime($user_time);
삽입 / 업데이트 date_created=$user_timestamp
.
date_created를 검색 할 때 다음과 같이 타임 스탬프를 변환 할 수 있습니다.
$date_created = // Get from the database
$created = date("F j, Y, g:i a",$date_created); // Return it to the user or whatever
이제이 예제는 first
타임 스탬프 를 삽입 할 때 필요에 맞을 수 있습니다 . 추가 타임 스탬프 나 테이블에 대해서는 나중에 참조 할 수 있도록 tzo 값을 users 테이블에 삽입하거나 설정하는 것이 좋습니다. 세션 또는 쿠키로.
추신 : 사용자가 여행하고 시간대를 전환하면 어떻게됩니까? GMT + 4에 로그인하고 GMT-1로 빠르게 이동 한 후 다시 로그인합니다. 마지막 로그인은 앞으로있을 것입니다.
내 생각 엔 ... 우리는 너무 많이 생각합니다.
PHP에서 유효한 TZ 데이터베이스 시간대 이름을 얻는 것은 두 단계 프로세스입니다.
JavaScript를 통해을 통해 분 단위로 시간대 오프셋을 가져옵니다 getTimezoneOffset
. 이 오프셋은 현지 시간대가 UTC보다 뒤에 있으면 양수이고, 앞에 있으면 네거티브입니다. 따라서 오프셋에 반대 부호를 추가해야합니다.
var timezone_offset_minutes = new Date().getTimezoneOffset();
timezone_offset_minutes = timezone_offset_minutes == 0 ? 0 : -timezone_offset_minutes;
이 오프셋을 PHP로 전달하십시오.
PHP에서이 오프셋을 timezone_name_from_abbr 함수 를 사용하여 유효한 시간대 이름으로 변환하십시오 .
// Just an example.
$timezone_offset_minutes = -360; // $_GET['timezone_offset_minutes']
// Convert minutes to seconds
$timezone_name = timezone_name_from_abbr("", $timezone_offset_minutes*60, false);
// America/Chicago
echo $timezone_name;</code></pre>
나는 블로그 게시물을 작성했다 : PHP에서 사용자 시간대를 감지하는 방법 . 또한 데모가 포함되어 있습니다.
Intl.DateTimeFormat().resolvedOptions().timeZone
웹 서버로 보내는 것입니다. 참조 : stackoverflow.com/questions/9772955/...
이를 수행하는 간단한 방법은 다음을 사용하는 것입니다.
new Date().getTimezoneOffset();
내가하는 방법은 다음과 같습니다. 이것은 PHP 기본 시간대를 사용자의 현지 시간대로 설정합니다. 모든 페이지 상단에 다음을 붙여 넣기 만하면됩니다.
<?php
session_start();
if(!isset($_SESSION['timezone']))
{
if(!isset($_REQUEST['offset']))
{
?>
<script>
var d = new Date()
var offset= -d.getTimezoneOffset()/60;
location.href = "<?php echo $_SERVER['PHP_SELF']; ?>?offset="+offset;
</script>
<?php
}
else
{
$zonelist = array('Kwajalein' => -12.00, 'Pacific/Midway' => -11.00, 'Pacific/Honolulu' => -10.00, 'America/Anchorage' => -9.00, 'America/Los_Angeles' => -8.00, 'America/Denver' => -7.00, 'America/Tegucigalpa' => -6.00, 'America/New_York' => -5.00, 'America/Caracas' => -4.30, 'America/Halifax' => -4.00, 'America/St_Johns' => -3.30, 'America/Argentina/Buenos_Aires' => -3.00, 'America/Sao_Paulo' => -3.00, 'Atlantic/South_Georgia' => -2.00, 'Atlantic/Azores' => -1.00, 'Europe/Dublin' => 0, 'Europe/Belgrade' => 1.00, 'Europe/Minsk' => 2.00, 'Asia/Kuwait' => 3.00, 'Asia/Tehran' => 3.30, 'Asia/Muscat' => 4.00, 'Asia/Yekaterinburg' => 5.00, 'Asia/Kolkata' => 5.30, 'Asia/Katmandu' => 5.45, 'Asia/Dhaka' => 6.00, 'Asia/Rangoon' => 6.30, 'Asia/Krasnoyarsk' => 7.00, 'Asia/Brunei' => 8.00, 'Asia/Seoul' => 9.00, 'Australia/Darwin' => 9.30, 'Australia/Canberra' => 10.00, 'Asia/Magadan' => 11.00, 'Pacific/Fiji' => 12.00, 'Pacific/Tongatapu' => 13.00);
$index = array_keys($zonelist, $_REQUEST['offset']);
$_SESSION['timezone'] = $index[0];
}
}
date_default_timezone_set($_SESSION['timezone']);
//rest of your code goes here
?>