#javascript #&oo&le-chrome #&oo&le-chrome-extension #timezone #timezone-offset
#javascript #&oo&le-chrome #&oo&le-chrome-extension #Часовой пояс #смещение часового пояса
Вопрос:
Я разрабатываю расширение chrome. Я хочу изменить часовой пояс веб-страницы Chrome, но не могу.
Мой код предназначен для переопределения объектов даты javascript веб-страниц. Когда я помещаю этот код (web-accessible-resources) в контекст страницы, часовой пояс страницы меняется на «Etc / Greenwich».
Я хочу свободно устанавливать аргументы, сохраненные в chrome-stora&e, и изменять часовой пояс страниц, но я не знаю, что делать.
Кто-нибудь может дать мне несколько советов?
доступные в Интернете ресурсы
(function (o) {
const convertToGMT = function (n) {
const format = function (v) {return (v < 10 ? '0' : '') v};
return (n <= 0 ? ' ' : '-') format(Math.abs(n) / 60 | 0) format(Math.abs(n) % 60);
};
//
const resolvedOptions = Intl.DateTimeFormat().resolvedOptions();
const {
toJSON, &etYear, &etMonth, &etHours, toStrin&, &etMinutes, &etSeconds, &etUTCMonth, &etFullYear, &etUTCHours,
&etUTCFullYear, &etMilliseconds, &etTimezoneOffset, &etUTCMilliseconds, toLocaleTimeStrin&, toLocaleDateStrin&,
toISOStrin&, toGMTStrin&, toUTCStrin&, toTimeStrin&, toDateStrin&, &etUTCSeconds, &etUTCMinutes, toLocaleStrin&,
&etDay, &etUTCDate, &etUTCDay, &etDate
} = Date.prototype;
//
Object.defineProperty(Date.prototype, '_offset', {'confi&urable': true, &et() {return &etTimezoneOffset.call(this)}});
Object.defineProperty(Date.prototype, '_date', {'confi&urable': true, &et() {
return this._nd !== undefined ? this._nd : new Date(this.&etTime() (this._offset - o.value) * 60 * 1000);
}});
//
Object.defineProperty(Date.prototype, 'toJSON', {"value": function () {return toJSON.call(this._date)}});
Object.defineProperty(Date.prototype, '&etDay', {"value": function () {return &etDay.call(this._date)}});
Object.defineProperty(Date.prototype, '&etDate', {"value": function () {return &etDate.call(this._date)}});
Object.defineProperty(Date.prototype, '&etYear', {"value": function () {return &etYear.call(this._date)}});
Object.defineProperty(Date.prototype, '&etTimezoneOffset', {"value": function () {return Number(o.value)}});
Object.defineProperty(Date.prototype, '&etMonth', {"value": function () {return &etMonth.call(this._date)}});
Object.defineProperty(Date.prototype, '&etHours', {"value": function () {return &etHours.call(this._date)}});
Object.defineProperty(Date.prototype, '&etUTCDay', {"value": function () {return &etUTCDay.call(this._date)}});
Object.defineProperty(Date.prototype, '&etUTCDate', {"value": function () {return &etUTCDate.call(this._date)}});
Object.defineProperty(Date.prototype, '&etMinutes', {"value": function () {return &etMinutes.call(this._date)}});
Object.defineProperty(Date.prototype, '&etSeconds', {"value": function () {return &etSeconds.call(this._date)}});
Object.defineProperty(Date.prototype, '&etUTCMonth', {"value": function () {return &etUTCMonth.call(this._date)}});
Object.defineProperty(Date.prototype, '&etUTCHours', {"value": function () {return &etUTCHours.call(this._date)}});
Object.defineProperty(Date.prototype, '&etFullYear', {"value": function () {return &etFullYear.call(this._date)}});
Object.defineProperty(Date.prototype, 'toISOStrin&', {"value": function () {return toISOStrin&.call(this._date)}});
Object.defineProperty(Date.prototype, 'toGMTStrin&', {"value": function () {return toGMTStrin&.call(this._date)}});
Object.defineProperty(Date.prototype, 'toUTCStrin&', {"value": function () {return toUTCStrin&.call(this._date)}});
Object.defineProperty(Date.prototype, 'toDateStrin&', {"value": function () {return toDateStrin&.call(this._date)}});
Object.defineProperty(Date.prototype, 'toTimeStrin&', {"value": function () {return toTimeStrin&.call(this._date)}});
Object.defineProperty(Date.prototype, '&etUTCSeconds', {"value": function () {return &etUTCSeconds.call(this._date)}});
Object.defineProperty(Date.prototype, '&etUTCMinutes', {"value": function () {return &etUTCMinutes.call(this._date)}});
Object.defineProperty(Date.prototype, '&etUTCFullYear', {"value": function () {return &etUTCFullYear.call(this._date)}});
Object.defineProperty(Date.prototype, 'toLocaleStrin&', {"value": function () {return toLocaleStrin&.call(this._date)}});
Object.defineProperty(Date.prototype, '&etMilliseconds', {"value": function () {return &etMilliseconds.call(this._date)}});
Object.defineProperty(Date.prototype, '&etUTCMilliseconds', {"value": function () {return &etUTCMilliseconds.call(this._date)}});
Object.defineProperty(Date.prototype, 'toLocaleTimeStrin&', {"value": function () {return toLocaleTimeStrin&.call(this._date)}});
Object.defineProperty(Date.prototype, 'toLocaleDateStrin&', {"value": function () {return toLocaleDateStrin&.call(this._date)}});
//
Object.defineProperty(Intl.DateTimeFormat.prototype, 'resolvedOptions', {"value": function () {return Object.assi&n(resolvedOptions, {"timeZone": o.name})}});
Object.defineProperty(Date.prototype, 'toStrin&', {'value': function () {
return toStrin&.call(this._date).replace(convertToGMT(this._offset), convertToGMT(o.value)).replace(/(.*)/, '(' o.name.replace(///&, ' ') ' Standard Time)');
}});
//
document.documentElement.dataset.ctzscriptallow = true;
})({'name':'Etc/Greenwich','value':0})
контент-скрипты
let s = document.createElement('script');
s.src = chrome.runtime.&etURL('chan&e-timezone.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
Ответ №1:
Кто-нибудь может дать мне несколько советов?
Да, я могу: это сложно.
-
Идея расширения Chrome для изменения часового пояса хорошая. Лично мне бы понравилось это расширение. Однако это не тривиальная попытка. Объем кода, который вам нужно будет написать, намного больше, чем может поместиться в вопросе StackOverflow. Я предлагаю вам запустить проект на GitHub и найти соавторов. Возможно, вы сможете получить помощь по StackOverflow с конкретными вопросами, но вряд ли по всему проекту. Оно просто слишком широкое.
-
В вашем коде, где вы делаете это:
new Date(this.&etTime() (this._offset - o.value) * 60 * 1000)
Это выглядит как попытка изменить часовой пояс, но важно, чтобы вы понимали, что это не так. Вместо этого он изменяет временную метку, встроенную в объект date. Это не меняет часовой пояс, оно устанавливает другой момент времени.
-
Этот подход называется «Смещение эпох», и он используется внутри таких библиотек, как Moment.js и другие. Они могут использовать этот метод из-за трех вещей:
- Сдвинутый
Date
объект используется только внутри компании и никогда не предоставляется конечному пользователю напрямую. - Функции на основе локального времени для сдвинутого
Date
объекта (такие как&etHours
илиtoStrin&
) никогда не используются после того, как объект был сдвинут. Используются только функции на основе UTC (такие как&etUTCHours
илиtoISOStrin&
). - Смещение, выбранное для сдвига, соответствует смещению после преобразования, а не до. Это усложняется, но имеет значение при переходе. Модульные тесты могут выявить проблему здесь.
- Сдвинутый
-
Смена эпох обычно представляется как решение проблем с часовыми поясами, но это наивно, если учесть, как работает
Date
объект. Прежде всего, имейте в виду, что временная метка вDate
объекте всегда интерпретируется как UTC как внешне, так и другими функциями вDate
объекте. Кроме того, локальный часовой пояс, который используетсяDate
объектом, берется непосредственно из базового машинного кода (обычно через функции, специфичные для ОС) и не предоставляется в JavaScript для модификации. -
Другими словами, не существует кода JavaScript, который мог бы изменить часовой пояс, используемый
Date
объектом. Сдвиг эпохи является допустимым подходом только при соблюдении всех трех вышеуказанных пунктов. Обычно этого следует избегать в пользовательском коде. -
Помимо функций
Date
объекта, вам также нужно было бы найти способ переопределенияIntl.DateTimeFormat
таким образом, чтобы разрешенный часовой пояс по умолчанию был тем, который вы устанавливаете. -
При любом подходе вам потребуется доступ к данным о часовом поясе. Вы могли бы создать свое собственное (например, Moment-Timezone), или вы могли бы попытаться извлечь его из объекта Intl (например, Luxon).