尝试开发Chrome扩展程序以自由更改TimeZone,但无法正常运行

问题描述

我正在开发Chrome扩展程序。 我想更改Chrome网页的TimeZone,但不能。

我的代码用于覆盖网页javascript日期对象。 当我将此代码(web-accessible-resources)放在页面上下文中时,页面的时区更改为'Etc / Greenwich'。

我想自由设置保存在chrome-storage的参数并更改页面时区, 但我不知道该怎么办。

有人可以给我一些建议吗?

网络可访问资源

(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,getYear,getMonth,getHours,toString,getMinutes,getSeconds,getUTCMonth,getFullYear,getUTCHours,getUTCFullYear,getMilliseconds,getTimezoneOffset,getUTCMilliseconds,toLocaleTimeString,toLocaleDateString,toISOString,toGMTString,toUTCString,toTimeString,toDateString,getUTCSeconds,getUTCMinutes,toLocaleString,getDay,getUTCDate,getUTCDay,getDate
  } = Date.prototype;
  //
  Object.defineProperty(Date.prototype,'_offset',{'configurable': true,get() {return getTimezoneOffset.call(this)}});
  Object.defineProperty(Date.prototype,'_date',get() {
    return this._nd !== undefined ? this._nd : new Date(this.getTime() + (this._offset - o.value) * 60 * 1000);
  }});
  //
  Object.defineProperty(Date.prototype,'toJSON',{"value": function () {return toJSON.call(this._date)}});
  Object.defineProperty(Date.prototype,'getDay',{"value": function () {return getDay.call(this._date)}});
  Object.defineProperty(Date.prototype,'getDate',{"value": function () {return getDate.call(this._date)}});
  Object.defineProperty(Date.prototype,'getYear',{"value": function () {return getYear.call(this._date)}});
  Object.defineProperty(Date.prototype,'getTimezoneOffset',{"value": function () {return Number(o.value)}});
  Object.defineProperty(Date.prototype,'getMonth',{"value": function () {return getMonth.call(this._date)}});
  Object.defineProperty(Date.prototype,'getHours',{"value": function () {return getHours.call(this._date)}});
  Object.defineProperty(Date.prototype,'getUTCDay',{"value": function () {return getUTCDay.call(this._date)}});
  Object.defineProperty(Date.prototype,'getUTCDate',{"value": function () {return getUTCDate.call(this._date)}});
  Object.defineProperty(Date.prototype,'getMinutes',{"value": function () {return getMinutes.call(this._date)}});
  Object.defineProperty(Date.prototype,'getSeconds',{"value": function () {return getSeconds.call(this._date)}});
  Object.defineProperty(Date.prototype,'getUTCMonth',{"value": function () {return getUTCMonth.call(this._date)}});
  Object.defineProperty(Date.prototype,'getUTCHours',{"value": function () {return getUTCHours.call(this._date)}});
  Object.defineProperty(Date.prototype,'getFullYear',{"value": function () {return getFullYear.call(this._date)}});
  Object.defineProperty(Date.prototype,'toISOString',{"value": function () {return toISOString.call(this._date)}});
  Object.defineProperty(Date.prototype,'toGMTString',{"value": function () {return toGMTString.call(this._date)}});
  Object.defineProperty(Date.prototype,'toUTCString',{"value": function () {return toUTCString.call(this._date)}});
  Object.defineProperty(Date.prototype,'toDateString',{"value": function () {return toDateString.call(this._date)}});
  Object.defineProperty(Date.prototype,'toTimeString',{"value": function () {return toTimeString.call(this._date)}});
  Object.defineProperty(Date.prototype,'getUTCSeconds',{"value": function () {return getUTCSeconds.call(this._date)}});
  Object.defineProperty(Date.prototype,'getUTCMinutes',{"value": function () {return getUTCMinutes.call(this._date)}});
  Object.defineProperty(Date.prototype,'getUTCFullYear',{"value": function () {return getUTCFullYear.call(this._date)}});
  Object.defineProperty(Date.prototype,'toLocaleString',{"value": function () {return toLocaleString.call(this._date)}});
  Object.defineProperty(Date.prototype,'getMilliseconds',{"value": function () {return getMilliseconds.call(this._date)}});
  Object.defineProperty(Date.prototype,'getUTCMilliseconds',{"value": function () {return getUTCMilliseconds.call(this._date)}});
  Object.defineProperty(Date.prototype,'toLocaleTimeString',{"value": function () {return toLocaleTimeString.call(this._date)}});
  Object.defineProperty(Date.prototype,'toLocaleDateString',{"value": function () {return toLocaleDateString.call(this._date)}});
  //
  Object.defineProperty(Intl.DateTimeFormat.prototype,'resolvedOptions',{"value": function () {return Object.assign(resolvedOptions,{"timeZone": o.name})}});
  Object.defineProperty(Date.prototype,'toString',{'value': function () {
    return toString.call(this._date).replace(convertToGMT(this._offset),convertToGMT(o.value)).replace(/\(.*\)/,'(' + o.name.replace(/\//g,' ') + ' Standard Time)');
  }});
  //
  document.documentElement.dataset.ctzscriptallow = true;
})({'name':'Etc/Greenwich','value':0})

内容脚本

let s = document.createElement('script');
s.src = chrome.runtime.getURL('change-timezone.js');

s.onload = function() {
  this.remove();
};
(document.head || document.documentElement).appendChild(s);

解决方法

有人可以给我一些建议吗?

是的,我可以:这很困难。

    Chrome扩展程序的
  • idea 可以更改时区,这是一个很好的选择。我个人很喜欢这种扩展。但是,这不是小事。您需要编写的代码量远远超过了StackOverflow问题中的代码量。我建议您启动一个GitHub项目并寻找合作者。您可能可以通过特定问题获得有关StackOverflow的帮助,但不可能针对整个项目。太宽了。

  • 在您的代码中,执行此操作的地方:

    new Date(this.getTime() + (this._offset - o.value) * 60 * 1000)
    

    这看起来像是尝试更改时区,但是了解这一点很重要。相反,它所做的是更改嵌入在date对象中的时间戳。不会更改时区,它会设置其他时间点

  • 该方法称为“时代转移”,Moment.js等库在内部使用该方法。他们可以使用此技术的原因有三点:

    1. 移位的Date对象仅在内部使用,绝不直接暴露给最终用户。
    2. 已移动的Date对象(例如getHourstoString)上的基于本地时间的函数一旦被移动,就永远不会使用。仅使用基于UTC的功能(例如getUTCHourstoISOString)。
    3. 选择要偏移的偏移量是之后的转换,而不是之前的。这变得很复杂,但在过渡阶段很重要。单元测试可以在这里揭示挑战。
  • 历时移位通常被提出来解决时区问题,但是当人们考虑Date对象的工作原理时,这是很幼稚的。首先,请记住,Date对象中的时间戳在外部和Date对象中的其他函数都始终被解释为UTC。另外,Date对象使用的本地时区直接来自底层的本机代码(通常通过特定于操作系统的功能),并且没有暴露给JavaScript进行修改。

  • 换句话说,没有一个JavaScript代码可以更改Date对象使用的时区。只有满足以上所有三个条件时,时代转移才是有效的方法。通常应在用户代码中避免使用此代码。

  • 除了Date对象的功能之外,您还必须找到一种方法来覆盖Intl.DateTimeFormat,以使默认的解析时区是您要设置的时区。

  • 通过任何方法,您都需要访问时区数据。您可以自带(例如Moment-Timezone),也可以尝试将其从Intl对象中拉出(例如Luxon)。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...