CreepJS 时区报告:偏移与位置字段
区分 CreepJS 时区字段、历史偏移比较和条件显示,明确它们与物理位置、身份及自动化判定的边界。
BotBrowser Team
CreepJS 时区报告结合了时区标识符、日期文本、历史计算与当前日期偏移。locationMeasured 这个名称不表示位置传感器测量了访问者。BotBrowser 支持时区、区域设置与语言配置,但不保证 CreepJS 分类,也不能让时区输出证明物理位置。报告差异要用于解释浏览器不一致,必须先明确各字段的输入与比较上下文。
摘要
location来自默认格式化器的时区标识符;zone来自 Date 字符串中的括号部分。locationMeasured使用固定历史比较与固定城市列表,不是地理坐标,也不是所有兼容时区的完整清单。- 历史比较使用
1113;offset与offsetComputed使用独立的当前日期路径。这并非同一测量重复三次。 - 渲染器各选择一个位置值与偏移值显示;两值不同时,对应的另一个值不会显示。
lied继承已有方法疑点。报告缺失、显示标签变化与继承疑点属于不同状态。
目录
七个字段与不同的产生方式
固定在修订 10aa6724cd33a1015db1574211890518cd04f0cc 的 CreepJS 时区模块返回七个具名属性。字段的来源比它们在卡片上的相邻位置更重要。时区标识符描述运行时选中的规则集;数值偏移描述某个日期的时差关系;时间戳描述日期构造得到的时刻。把三者统一转成一个“位置”答案,会丢掉诊断差异所需的区别。
location 起始于 Intl.DateTimeFormat().resolvedOptions().timeZone。格式化器没有指定显式时区,因此字段反映运行时的默认选择,而不是定位用户的请求。模块随后对标识符作显示处理:把一个下划线替换成空格,并把斜杠改成逗号分隔符。因此,显示的位置标签并不是未经修改的标识符字符串。若对比涉及拼写或别名,应单独保留原始标识符。
zone 使用不同来源。它把一个新建 Date 转成文本,再提取去括号表达式选中的部分。这并不是再次调用 resolvedOptions()。Date 文本与 IANA 时区标识符可以采用不同名称、承担不同用途,而不构成相互矛盾。面向人的时区描述不能替代应用程序 timeZone 选项要求的标识符。
| 字段 | 固定修订中的产生方式 | 最多能够支持的解释 |
|---|---|---|
zone | 从新建 Date 字符串选出的文本 | 该字符串中的显示描述 |
location | 默认格式化器时区,再作显示处理 | 以标签展示的报告时区标识符 |
locationMeasured | 历史比较与条件候选摘要 | 源码定义的比较结果 |
locationEpoch | 本地历史日期的数值转换 | 构造出的历史时间戳 |
offset | 新建 Date 的 getTimezoneOffset() | 该实例表示日期的偏移 |
offsetComputed | 两个分别解析的日期字符串之差 | 使用不同构造规则的当前日期计算 |
lied | 已有疑点项中的首个真值,否则为 false | 继承的评估,而非新位置测量 |
CreepJS Intl 报告分析将格式化样本与构造器区域设置采集分开。时区卡片同样需要区分来源,但它的字段并不是 Intl 采集函数的六个格式化回调产生的。日期标签出现在时区字段旁边,并不意味着两个模块可以互换。在同一对比记录中保留源码修订、返回属性与渲染行,才能避免把不同采集函数的值悄然配对。
locationEpoch 特别容易被误认为采集时间。源码使用 1113 年 7 月 1 日构造日期,再转成数字。该数字不是获得同意的位置 API 提供的,也不记录报告页面打开的时间。支持系统若将它存入“最近出现”列,就会在自己的数据模型中引入错误,即使显示数字与检测器输出完全一致。
历史偏移与有界候选搜索
历史路径比较同一选定年份下的两种计算。一种遵循系统本地日期构造;另一种通过 Intl.DateTimeFormat 使用显式时区。源码选择 1113 与 7 月日期。它并不是把今天的偏移直接与历史偏移相比,再把相等宣称为地理匹配。当前字段 offset 与 offsetComputed 在采集函数后面独立组装。
两种历史结果一致时,候选缩减从报告的时区本身开始。否则,模块搜索内置 cities 列表,找出历史计算等于系统结果的条目。这是源码定义的时区名称集合,不是实时地理目录。列表成员属于固定修订的一部分。一个时区即使被运行时识别,只要不在列表中,也不会因此成为搜索发现的候选。
递归辅助函数进一步限制了“匹配集合”的含义。它先过滤列表左侧部分,找到匹配子集就返回;只有左侧为空才递归右侧。它不会把两半中的所有匹配合并成全局结果。因此,把输出描述成与某次观察兼容的全部时区,会超过实际搜索能够支持的范围。列表与搜索策略共同约束了最终子集。
最后的缩减只有在子集恰好一个成员、且该成员等于报告时区时,才保留名称。其他结果交给项目的紧凑摘要辅助函数处理。locationMeasured 中的紧凑值不是浏览器发现却拒绝透露的城市名。两个摘要相同,也不能证明完整时区数据库相同。原始成员与搜索上下文属于显示摘要没有暴露的信息。
IANA 的时区理论文档解释了历史数据为何需要额外限定。主要兼容范围涉及 1970 年后时钟一致的地区,更早记录可能不完整,地理覆盖也有限。1113 的日期可以用于分析两条软件路径如何使用历史规则,但不是独立验证过的访问者中世纪位置记录。若观察到差异,必须先明确浏览器、运行时数据与日期构造上下文,才能归因于某个原因。
名称、规则与地理
时区标识符指向与代表性地点关联的规则历史,不是当前 GPS 定位。多个地点可以在某一时刻共享偏移,一个人也可以选择与当前位置无关的时区。ICU 别名与时区对比在另一套有记录的环境中讨论报告名称与固定偏移比较。它的输出不能当作对这个固定 CreepJS 模块的测量。
即使没有运行浏览器,源码推导的边界仍有价值。locationMeasured 可归类为保留的报告名称,或紧凑候选结果。这种分类标明产生该值的比较分支,但不认证国家、网络路径或个人。有关坐标的任何主张都需要位置接口及其权限上下文的证据;两者均不是此时区采集函数的输入。
两条当前日期偏移路径
直接字段 offset 读取 new Date().getTimezoneOffset()。MDN 定义其结果单位为分钟:本地时区落后 UTC 时为正,领先 UTC 时为负。实例表示的日期很重要,因为夏令时与历史规则可以让不同日期的偏移发生变化。因此,应将偏移与取得它所用的时刻或日期绑定,而不是存成时区名称的永久属性。
offsetComputed 辅助函数的起点不同。它提取新生成 ISO 日期字符串的日期部分,以不同格式构造两个日期字符串,减去两者的数值日期,再转换成分钟。ISO 日期部分遵循 UTC 日历日,在午夜附近未必与主机本地日历日相同。该函数不是再次调用直接偏移方法;比较时钟切换附近的结果时,所选日期构造方式很重要。
一种构造形式是 ISO 纯日期字符串,另一种用斜杠分隔月、日、年。ECMA-262 规定纯日期形式按 UTC 解释。MDN 指出非标准形式的解析可能随实现变化。源码解释可以明确这些输入形式,但“所有浏览器都相同地解析斜杠形式”需要超出标准日期时间字符串规则的证据。计算结果不能被提升为独立参考时钟。
辅助函数对分钟差应用 ~~。该运算执行整数转换,不记录原始毫秒,也不会给结果附上异常类别。转换后的数值相同,弱于完整中间输入的比较。报告若只保留最终偏移行,就无法通过更精细地阅读数字或在旁边增加时区缩写来恢复构造细节。
对时钟切换敏感的比较
一个假设在夏令时切换附近采集的报告,可以说明输入问题。offset 使用的新 Date 与 offsetComputed 使用的基于日历的字符串,未必表示同一时刻。因此出现差异时,可能要先检查日期选择,再调查 API 修改。这是解释场景,不是观察到的浏览器结果。仅阅读采集函数源码,无法证明某次切换的具体输出。
对比记录可以在不保存完整指纹的情况下消除歧义。保留采集时间、时区标识符、两个偏移字段原始值与源码修订。若问题涉及切换,保留实际构造的精确日期。没有日期的偏移无法证明应用了哪条夏令时规则;渲染器把两个数字合成一条选择性显示行,也无法证明产生路径相同。
条件显示与继承疑点
正常渲染器不会为每次比较输出带标签的一对值。位置两值不同时选择 locationMeasured,否则选择 location;偏移两值不同时选择 offsetComputed,否则选择 offset。因此卡片截图恰恰可能在存在差异时省略另一个值。因为只看见一个数字就推断一致,颠倒了条件显示实际能够证明的内容。
正常卡片还会在 zone 为真值时显示它,并输出 locationEpoch。这些显示选择说明各行来源,但不能让行顺序变成完整诊断记录。标签缺失不自动意味着时区 API 失败。渲染值与底层对象包含的信息不同;用于诊断不匹配的对比应保留具名原始字段,而不仅是卡片的视觉顺序。
lied 属性以 JavaScript 的 || 运算符组合三个预先填入的疑点键,最后回退到 false。它保留首个真值操作数,并不是三项发现的计数。更关键的是,时区采集函数并非通过检验 offset 是否等于 offsetComputed,或显示位置是否像城市名来设置该属性。继承疑点与本地字段差异必须保持为独立观察。
外层采集块抛出异常时,模块记录采集失败、捕获错误,并且不返回报告对象。渲染器检查 fp.timezone 缺失,选择 blocked 注记。单靠注记无法识别是哪一次构造、解析、属性访问或历史操作失败。支持说明若仅根据标签就指定失败 API,会超出已有证据进行猜测。
| 可见情况 | 还需要的字段 | 缺少时能够得出的结论 |
|---|---|---|
| 只有一行偏移 | offset 与 offsetComputed 两者 | 渲染器选中了一个值,是否一致未知 |
| 出现紧凑位置值 | location、locationMeasured 与修订 | 显示的是源码定义的摘要,不是坐标 |
| 卡片带疑点样式 | 原始疑点项 | 继承评估影响了显示 |
| 出现 blocked 卡片 | 采集函数是否存在及捕获的错误上下文 | 该分支无法获得正常报告对象 |
对比场景与有效记录
zone 描述改变、标识符不变,属于文本层比较。应调查 Date 文本与已记录 location 来源之间的差异,而不是据此证明两个设备位于不同地区。时区标识符改变,则涉及格式化器解析与配置。这些情况对应不同的后续检查,即使口头上都被称作“时区变化”报告。
location 保持不变而 locationMeasured 改变,涉及历史比较或固定列表缩减。首先应比较 CreepJS 修订与运行时时区数据,而不是新增访问者移动的主张。locationEpoch 改变也涉及构造的历史日期。分别保留这些属性,可以避免支持系统把软件数据差异转成无根据的真实旅行事件。
时区命名稳定时,offset 改变可能符合日期相关规则。记录必须带日期,才能区分夏令时变化与配置变化。反过来,偏移相同也不能证明时区规则集相同:单个时刻无法描述所有历史或未来切换。有用的比较是在明确输入下对比具名字段,而不是笼统断言两个环境拥有相同身份。
BotBrowser 时区文档描述自动默认值、显式覆盖,以及单独的区域设置与语言控制。这些文档设置提供配置上下文,但不认证采集函数的历史计算,也不认证外部网站的解释。调查应先明确预期设置与实际报告值。单纯为了移除检测器标签而改配置,会用期望的外观代替对原始差异的解释。
有界支持记录应保留工具修订、采集日期、浏览器构建、预期时区设置与相关具名字段。缺失就记作缺失,并区分对象缺失与显示描述缺失。解释某一时区行来自哪个分支,不需要原始组合指纹或无关浏览数据。如果有错误,可保留去敏后的类别以识别失败操作,不采集无关页面内容。
常见问题:时区报告边界
locationMeasured 是否使用浏览器地理位置权限?
固定修订中的产生路径使用历史 Date、Intl 计算与城市列表,不请求地理坐标。字段名不是权限弹窗、GPS 观察或当前国家的证据。
locationEpoch 是否是报告采集时间?
不是。它来自使用 1113 构造的本地历史 7 月日期。采集时间应另记。将历史时间戳用作报告时间戳,会改变该值的含义。
当前偏移相同能否验证历史比较?
不能。offset 与 offsetComputed 使用当前日期路径,候选路径使用选定历史年份。一种比较一致,不能证明另一组输入或完整时区历史也一致。
为什么存在不匹配时截图仍可能只有一个偏移?
offsetComputed 与 offset 不同时,渲染器选择前者,而不分别标注两者。要区分相等与这个不匹配选择分支,需要原始对象。
lied 是否统计时区不匹配次数?
已检查的采集函数继承三个方法条目中的首个真值疑点,不根据显示位置或偏移行计算不匹配次数。疑点来源需要单独证据。
BotBrowser 配置能否证明访问者物理位置?
时区、区域设置与语言控制描述浏览器配置,不证明个人坐标,也不保证检测器分类。报告时区与物理位置测量回答不同问题。
来源
- CreepJS:固定修订的时区采集函数与渲染器
- CreepJS:固定修订的摘要辅助函数
- CreepJS:固定修订的错误辅助函数
- MDN:Date.getTimezoneOffset
- MDN:Date.parse 与非标准输入
- MDN:DateTimeFormat.resolvedOptions
- ECMA-262:数字与日期
- IANA:时区数据库理论
- BotBrowser:时区、区域设置与语言设置
实践结论
时区报告的价值依赖于保留各字段的来源与日期。将解析标识符与 Date 文本、历史候选路径、两条当前日期偏移路径分开。检查渲染器所选行背后的两个原始值,并先追溯继承疑点,再指定失败原因。这些区分支持具体的不一致调查,而不会把时区输出变成物理位置、个人身份或第三方自动化判定。
本文属于指南: 什么是浏览器指纹?原理、风险、信号与隐私边界