1
new Date('April 12, 2012 05:00:00 ').toLocaleString();

日付自体は、PHP を介して提供およびフォーマットされています。ただし、ユーザーがログインしていない場合、タイムゾーンのオフセットがわからないため、JavaScript の使用を余儀なくされています。

オフセットを見つけて適用し、それをすべて 1 行のコードに保持するにはどうすればよいですか?

4

2 に答える 2

1

ごめん。日付は難しいです。

可能であれば、サーバーに日付文字列をフォーマットさせ、Webページやajax応答などを使用してブラウザーに送信します。

本当に、本当に、本当に本当にjavascriptでクライアントのタイムゾーン変換を実行したい場合は、関心のあるタイムゾーンルールをクライアントに送信する必要があります。Windowsマシンを使用している場合、以下は、タイムゾーンルールと変換を実行する関数を含むjavascriptファイルを生成するPowerShellスクリプトです。サードパーティのWebAPIからブラウザのタイムゾーンとは異なるタイムゾーンに日付を変換する必要がある場合にこれを使用しました。

このアプローチは、ブラウザのタイムゾーンまたはUTC以外のタイムゾーンに日付オブジェクトを取得する必要がある場合にのみ実行する必要があります。それでも、代わりに日付をフォーマットするWebサービスを検討することもできます。

# Serialize .Net TimeZoneInfo objects to a javascript file.
Add-Type -AssemblyName System.Web.Extensions;
$f = "timezoneinfo.js";
$ser = new-object System.Web.Script.Serialization.JavaScriptSerializer;
$tzi = [System.TimeZoneInfo]::FindSystemTimeZoneById("Central Standard Time");

# To keep the file size reasonable, exclude timezoneinfos where this web site has no activity.
$exclude = @("Afghanistan Standard Time",
"Arab Standard Time",
"Arabian Standard Time",
"Arabic Standard Time",
"Argentina Standard Time",
"Atlantic Standard Time",
"AUS Central Standard Time",
"AUS Eastern Standard Time",
"Azerbaijan Standard Time",
"Azores Standard Time",
"Bangladesh Standard Time",
"Cape Verde Standard Time",
"Caucasus Standard Time",
"Cen. Australia Standard Time",
"Central America Standard Time",
"Central Asia Standard Time",
"Central Brazilian Standard Time",
"Central Europe Standard Time",
"Central European Standard Time",
"Central Pacific Standard Time",
"China Standard Time",
"Dateline Standard Time",
"E. Africa Standard Time",
"E. Australia Standard Time",
"E. Europe Standard Time",
"E. South America Standard Time",
"Egypt Standard Time",
"Ekaterinburg Standard Time",
"Fiji Standard Time",
"FLE Standard Time",
"Georgian Standard Time",
"Greenland Standard Time",
"Greenwich Standard Time",
"Hawaiian Standard Time",
"India Standard Time",
"Iran Standard Time",
"Israel Standard Time",
"Jordan Standard Time",
"Kaliningrad Standard Time",
"Kamchatka Standard Time",
"Korea Standard Time",
"Magadan Standard Time",
"Mauritius Standard Time",
"Mid-Atlantic Standard Time",
"Middle East Standard Time",
"Montevideo Standard Time",
"Morocco Standard Time",
"Myanmar Standard Time",
"N. Central Asia Standard Time",
"Namibia Standard Time",
"Nepal Standard Time",
"Newfoundland Standard Time",
"North Asia East Standard Time",
"North Asia Standard Time",
"Pacific SA Standard Time",
"Pakistan Standard Time",
"Paraguay Standard Time",
"Romance Standard Time",
"Russian Standard Time",
"SA Eastern Standard Time",
"SA Pacific Standard Time",
"SA Western Standard Time",
"Samoa Standard Time",
"SE Asia Standard Time",
"Singapore Standard Time",
"Sri Lanka Standard Time",
"Syria Standard Time",
"Taipei Standard Time",
"Tasmania Standard Time",
"Tokyo Standard Time",
"Tonga Standard Time",
"Turkey Standard Time",
"Ulaanbaatar Standard Time",
"Venezuela Standard Time",
"Vladivostok Standard Time",
"W. Australia Standard Time",
"W. Central Africa Standard Time",
"W. Europe Standard Time",
"West Asia Standard Time",
"West Pacific Standard Time",
"Yakutsk Standard Time");

"/*This file was generated by a tool*/" | out-file $f;
"(function (TimeZoneInfo, undefined) {" | out-file $f -Append;

$first = $true;
"var infos = {" | out-file $f -Append;
[System.TimeZoneInfo]::GetSystemTimeZones() | ? {
    $exclude -notcontains $_.Id} | % {

    # Serizliae the TimeZoneInfo
    $s1 = $ser.Serialize($_);
    # Serialize the adjustment rules.  Convert MS Ajax dates into JS date constructors.
    $s2 = $ser.Serialize($_.GetAdjustmentRules()) -replace "\`"\\/Date\((?<ticks>.+?)\)\\/\`"", "new Date(`$1)";
    # Add the adjustment rules to the resulting JSON.
    $s3 = $s1.Substring(0, $s1.Length - 1) + ",AdjustmentRules:" + $s2 + "}";
    # Add item to associative JS array.
    $s3 = "`"" + $_.ID + "`":" + $s3;
    if (!$first) {      
        $s3 = "," + $s3;
        $s3 | write-host;
    } else {
        $first = $false;        
    }

    # Cheesy code here.  But the next few steps remove properties we don't care about to get keep the file size down.
    # Remove strings.
    $s3 = $s3 -replace "`"(Id|DisplayName|StandardName|DaylightName)`":`".+?`"(,)?", "";
    # Remove all of the TimeSpan properties except TotalMinutes.
    $s3 = $s3 -replace "`"(Ticks|Days|Hours|Milliseconds|Minutes|Seconds|TotalDays|TotalHours|TotalMilliseconds)`":[-0-9.]+?,", "";
    $s3 = $s3 -replace ",`"TotalSeconds`":(-)?\d+", "";

    $s3 | out-file $f -Append;
}
"};" | out-file $f -Append;


# Add the client function to do the conversion.  This mainly comes from using reflector and looking as MSDN for IsFixedDateRule.
$s4 = "
// This function will shift a date the approprate number of hours to make it appear correct for the given timezoneid.
TimeZoneInfo.ConvertTime = function(dt, tzid) {
    if (typeof(dt) === `"undefined`" || dt == null) { return null; }
    if (typeof(tzid) === `"undefined`" || tzid == null || tzid === `"`") { return dt; }
    var tz = infos[tzid];
    if (typeof(tz) === `"undefined`") { return dt; }

    var clientOffset = dt.getTimezoneOffset();

    var adj = null;
    var j = tz.AdjustmentRules.length;  
    for (var i = 0; i < j; i++) {
        if (tz.AdjustmentRules[i].DateStart <= dt) {
            if (tz.AdjustmentRules[i].DateEnd >= dt) {
                adj = tz.AdjustmentRules[i];
                break;
            }
        } 
    }

    function GetDaysInMonth(y, m)
    {
        return 32 - new Date(y, m, 32).getDate();
    }

    function GetTransitionDayOfMonth(t, y) {
        var startOfWeek = t.Week * 7 - 6;
        var firstDayOfWeek = new Date(y, t.Month - 1, 1).getDay();
        var transitionDay = null;
        var changeDayOfWeek = t.DayOfWeek;
        if (firstDayOfWeek <= changeDayOfWeek) {
            transitionDay = startOfWeek + (changeDayOfWeek - firstDayOfWeek);
        } else {
            transitionDay = startOfWeek + (7 - firstDayOfWeek + changeDayOfWeek);
        }
        if (transitionDay > GetDaysInMonth(y, t.Month - 1)) {
            transitionDay -= 7;
        }
        return transitionDay;
    }

    var dstOffset = 0;
    if (adj != null) {
        var dstStart = adj.DaylightTransitionStart.IsFixedDateRule ?
            new Date(dt.getFullYear(), adj.DaylightTransitionStart.Month - 1, adj.DaylightTransitionStart.Day, adj.DaylightTransitionStart.TimeOfDay.getHours()) :
            new Date(dt.getFullYear(), adj.DaylightTransitionStart.Month - 1, GetTransitionDayOfMonth(adj.DaylightTransitionStart, dt.getFullYear()), adj.DaylightTransitionStart.TimeOfDay.getHours());
        var dstEnd = adj.DaylightTransitionEnd.IsFixedDateRule ?
            new Date(dt.getFullYear(), adj.DaylightTransitionEnd.Month - 1, adj.DaylightTransitionEnd.Day, adj.DaylightTransitionEnd.TimeOfDay.getHours()) :
            new Date(dt.getFullYear(), adj.DaylightTransitionEnd.Month - 1, GetTransitionDayOfMonth(adj.DaylightTransitionEnd, dt.getFullYear()), adj.DaylightTransitionEnd.TimeOfDay.getHours());
        if (dstStart <= dt && dstEnd >= dt) {
            dstOffset = adj.DaylightDelta.TotalMinutes;
        }
    }
    var dtcopy = new Date(dt.getTime());
    dtcopy.setMinutes(dtcopy.getMinutes() + clientOffset + tz.BaseUtcOffset.TotalMinutes + dstOffset);
    return dtcopy;  
};
TimeZoneInfo.Get = function(tzid) { return infos[tzid]; };
";


$s4 | out-file $f -Append;


"} (window.TimeZoneInfo = window.TimeZoneInfo || {}));" | out-file $f -Append;

#//TimeZoneInfo.ConvertTime(new Date(2011,7,1,16,45), "Central Standard Time");
#//TimeZoneInfo.ConvertTime(new Date(2011,7,1,16,45), "Eastern Standard Time");
#//TimeZoneInfo.ConvertTime(new Date(2011,7,1,16,45), "South Africa Standard Time");
#notepad.exe $f;
于 2012-04-10T22:13:23.120 に答える
0

ユーザーのタイム ゾーンを検出しようとしないでください。代わりに、時刻を UNIX 時間 (1970 年 1 月 1 日 00:00 UTC の秒数) で渡し、そこから設定します。

d = new Date(); d.setTime(the_time_value);

これにより、ブラウザのローカル タイム ゾーンに従って、渡された時刻に設定された Date が生成されます。

PHPでは、日付/時刻をUNIX時間に変換できます$date->getTimestamp();

経験則では、常に UTC でプログラムの周り (ブラウザーとサーバーの間を含む) を保存して渡し、できるだけ遅くローカルの日付/時刻に変換します。

于 2012-04-10T22:19:26.207 に答える