javascript - للسعودية - المنطقة الزمنية للمملكة العربية السعودية




تحديد المنطقة الزمنية للمستخدم (16)

هل هناك طريقة قياسية لخادم الويب لتكون قادرة على تحديد المنطقة الزمنية للمستخدم داخل صفحة ويب؟

ربما من رأس HTTP أو جزء من سلسلة user-agent ؟


أحد الخيارات الممكنة هو استخدام Date حقل الرأس ، والذي تم تعريفه في RFC 7231 ومن المفترض أن يتضمن المنطقة الزمنية. بالطبع ، ليست مضمونة أن تكون القيمة حقًا هي المنطقة الزمنية للعميل ، ولكن يمكن أن تكون نقطة انطلاق ملائمة.


إليك كيف أفعل ذلك. سيؤدي ذلك إلى ضبط المنطقة الزمنية الافتراضية لـ 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
?>

جرب كود PHP هذا:

<?php
    $ip = $_SERVER['REMOTE_ADDR'];
    $json = file_get_contents("http://api.easyjquery.com/ips/?ip=" . $ip . "&full=true");
    $json = json_decode($json,true);
    $timezone = $json['LocalTimeZone'];
?>

هناك طريقة بسيطة للقيام بذلك باستخدام:

new Date().getTimezoneOffset();

JavaScript هي أسهل طريقة للحصول على الوقت المحلي للعميل. أود أن أقترح استخدام XMLHttpRequest لإرسال الوقت المحلي ، وإذا فشل ذلك ، يمكنك الرجوع إلى المنطقة الزمنية المكتشفة بناءً على عنوان IP الخاص بهم.

بقدر ما تحديد الموقع الجغرافي ، لقد استخدمت MaxMind GeoIP في العديد من المشاريع ، وأنها تعمل بشكل جيد ، على الرغم من أنني لست متأكدا مما إذا كانت توفر بيانات المنطقة الزمنية. إنها خدمة تدفعها وتوفر تحديثات شهرية لقاعدة البيانات الخاصة بك. أنها توفر مغلفة في العديد من لغات الويب.


أولاً ، فهم أن اكتشاف المنطقة الزمنية في JavaScript غير كامل. يمكنك الحصول على إزاحة المنطقة الزمنية المحلية لتاريخ ووقت getTimezoneOffset باستخدام getTimezoneOffset في مثيل لكائن Date ، لكن هذا لا يختلف تمامًا عن منطقة زمنية IANA كاملة مثل America/Los_Angeles .

هناك بعض الخيارات التي يمكن أن تعمل على الرغم من:

  • تدعم معظم المتصفحات الحديثة مناطق زمنية IANA في تنفيذها لواجهة برمجة تطبيقات ECMAScript ، بحيث يمكنك القيام بذلك:

    const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;

    والنتيجة هي سلسلة تحتوي على إعداد المنطقة الزمنية IANA للكمبيوتر حيث يتم تشغيل التعليمات البرمجية.

    يتم سرد البيئات المدعومة في جدول توافق Intl . قم بتوسيع قسم DateTimeFormat ، وانظر إلى الميزة المسمى resolvedOptions().timeZone defaults to the host environment .

    • تستخدم بعض المكتبات ، مثل Luxon واجهة برمجة التطبيقات هذه لتحديد المنطقة الزمنية من خلال وظائف مثل luxon.Settings.defaultZoneName .
  • إذا كنت بحاجة إلى دعم مجموعة أكبر من البيئات ، مثل متصفحات الويب الأقدم ، فيمكنك استخدام مكتبة لتخمين متعلم في المنطقة الزمنية. إنها تعمل عن طريق تجربة API Intl أولاً إذا كانت متوفرة ، وعندما لا تكون متاحة ، فإنها تستجوب الدالة getTimezoneOffset لكائن Date ، لعدة نقاط مختلفة في الوقت المناسب ، وذلك باستخدام النتائج لاختيار منطقة زمنية مناسبة من مجموعة بيانات داخلية.

    كل من https://bitbucket.org/pellepim/jstimezonedetect و moment-timezone لهما هذه الوظيفة.

    // using jsTimeZoneDetect
    var tzid = jstz.determine().name();
    
    // using moment-timezone
    var tzid = moment.tz.guess();

    في كلتا الحالتين ، يمكن اعتبار النتيجة مجرد تخمين. قد يكون التخمين صحيحًا في العديد من الحالات ، ولكن ليس جميعها.

    بالإضافة إلى ذلك ، يجب تحديث هذه المكتبات بشكل دوري لمواجهة حقيقة أن العديد من تطبيقات جافا سكريبت القديمة تدرك فقط قاعدة التوقيت الصيفي الحالية لمنطقتها الزمنية المحلية. مزيد من التفاصيل حول هذا هنا.

في النهاية ، تتمثل الطريقة الأفضل في طلب المستخدم فعليًا لمنطقته الزمنية. توفير الإعداد التي يمكنهم تغييرها. يمكنك استخدام أحد الخيارات المذكورة أعلاه لاختيار إعداد افتراضي ، ولكن لا تجعل من المستحيل الخروج عن ذلك في تطبيقك.

هناك أيضًا طريقة مختلفة تمامًا تتمثل في عدم الاعتماد على إعداد المنطقة الزمنية لجهاز الكمبيوتر الخاص بالمستخدم على الإطلاق. بدلاً من ذلك ، إذا كان يمكنك تجميع إحداثيات خطوط الطول والعرض ، فيمكنك حلها إلى منطقة زمنية باستخدام إحدى هذه الطرق . هذا يعمل بشكل جيد على الأجهزة المحمولة.



إليك طريقة أكثر اكتمالا.

  1. الحصول على تعويض المنطقة الزمنية للمستخدم
  2. اختبر بعض الأيام على حدود التوقيت الصيفي لتحديد ما إذا كانت موجودة في منطقة تستخدم التوقيت الصيفي.

مقتطف أدناه:

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

الحصول على TZ و DST من JS (عبر آلة رجوع الطريق)


السحر يبدو أن كل شيء في

visitortime.getTimezoneOffset()

هذا رائع ، لم أكن أعرف ذلك. هل يعمل في Internet Explorer ، إلخ؟ من هناك يجب أن تكون قادرًا على استخدام JavaScript إلى Ajax ، وتعيين ملفات تعريف الارتباط ، أيا كان. ربما سأذهب إلى ملف تعريف الارتباط.

ستحتاج إلى السماح للمستخدم بتغييره بالرغم من ذلك. لقد حاولنا استخدام الموقع الجغرافي (عبر maxmind) للقيام بذلك منذ فترة ، وكان من الخطأ في كثير من الأحيان بشكل معقول - بما يكفي لجعل الأمر لا يستحق القيام به ، لذلك دعونا فقط للمستخدم تعيينه في ملفه الشخصي ، وإظهار إشعار للمستخدمين الذين لم تحدد لهم حتى الآن.


الطريقة الأكثر شيوعًا (== القياسية؟) لتحديد المنطقة الزمنية التي رأيتها حولها هي ببساطة سؤال المستخدمين أنفسهم. إذا كان موقع الويب الخاص بك يتطلب اشتراكًا ، فيمكن حفظ هذا في بيانات الملف الشخصي للمستخدمين. بالنسبة إلى مستخدمي anon ، يمكن عرض التواريخ كـ UTC أو GMT أو بعضها.

أنا لا أحاول أن أكون aleck الذكية. في بعض الأحيان يكون لبعض المشاكل حلول أدق خارج أي سياق برمجة.


جافا سكريبت:

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

ما عليك سوى توفير أوقاتك بتنسيق يونيكس الزمني لهذه الوظيفة ؛ جافا سكريبت يعرف بالفعل المنطقة الزمنية للمستخدم.

مثله:

PHP:

echo '<script type="text/javascript">
var eltimio = maketimus('.$unix_timestamp_ofshiz.');
document.write(eltimio);
</script><noscript>pls enable javascript</noscript>';

سيُظهر هذا دائمًا الأوقات بشكل صحيح استنادًا إلى المنطقة الزمنية التي حددها الشخص على ساعة جهاز الكمبيوتر الخاص به. ليست هناك حاجة لطرح أي شيء على أي شخص وحفظه في أماكن والحمد لله!


سهل ، فقط استخدم وظيفة JavaScript getTimezoneOffset مثل:

-new Date().getTimezoneOffset()/60;

لإرسال إزاحة المنطقة الزمنية كرأس HTTP على طلبات AJAX باستخدام jQuery

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        xhr.setRequestHeader("X-TZ-Offset", -new Date().getTimezoneOffset()/60);
    }
});

يمكنك أيضًا القيام بشيء مماثل للحصول على اسم المنطقة الزمنية الفعلي باستخدام moment.tz.guess(); من http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/


لا تستخدم عنوان IP لتحديد الموقع بشكل نهائي (وبالتالي المنطقة الزمنية) - لأنه بسبب NAT ، الوكلاء (الأكثر شيوعًا بشكل متزايد) ، و VPN ، لا تعكس عناوين IP بشكل واقعي الموقع الفعلي للمستخدم ، ولكن الموقع الذي الخوادم التي تنفذ تلك البروتوكولات الموجودة.

على غرار الطريقة التي لم تعد بها رموز المنطقة في الولايات المتحدة مفيدة لتحديد موقع مستخدم الهاتف ، بالنظر إلى شعبية إمكانية نقل الأرقام.

تعد عناوين IP والتقنيات الأخرى الموضحة أعلاه مفيدة في اقتراح افتراضي يمكن للمستخدم ضبطه / تصحيحه.


ما زلت لم أر إجابة مفصلة هنا أن يحصل على المنطقة الزمنية. يجب ألا تحتاج إلى الترميز الجغرافي بواسطة عنوان IP أو استخدام PHP (لول) أو تخمين غير صحيح من الإزاحة.

أولاً ، المنطقة الزمنية ليست مجرد إزاحة من GMT. إنها مساحة من الأرض يتم فيها تحديد قواعد الوقت وفقًا للمعايير المحلية. بعض الدول لديها وفورات الصيفي ، وسيتم تشغيل التوقيت الصيفي في أوقات مختلفة. من المهم عادة الحصول على المنطقة الفعلية ، وليس فقط الإزاحة الحالية.

إذا كنت تنوي تخزين هذه المنطقة الزمنية ، على سبيل المثال في تفضيلات المستخدم ، فأنت تريد المنطقة وليس الإزاحة فقط. بالنسبة للتحويلات في الوقت الفعلي ، لن يكون الأمر مهمًا.

الآن ، للحصول على المنطقة الزمنية باستخدام javascript ، يمكنك استخدام هذا:

>> new Date().toTimeString();
"15:46:04 GMT+1200 (New Zealand Standard Time)"
//Use some regular expression to extract the time.

ومع ذلك ، فقد وجدت أنه من الأسهل استخدام هذا المكون الإضافي القوي الذي يعرض المنطقة الزمنية المنسقة في Olsen:

https://github.com/scottwater/jquery.detect_timezone


مع وظيفة date PHP ، ستحصل على تاريخ وقت الخادم الذي يوجد عليه الموقع. الطريقة الوحيدة للحصول على وقت المستخدم هي استخدام 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();
?>

ولكن من وجهة نظري ، من الأفضل أن تسأل المستخدمين عما إذا كان التسجيل إلزاميًا في مشروعك.





timezone-offset