Javascript 如何将日期和时间输入视为本地时间,而不是世界时间?

Javascript 如何将日期和时间输入视为本地时间,而不是世界时间?,javascript,date,time,timezone,Javascript,Date,Time,Timezone,用户输入的日期输入2019-12-22给出以下值: 输入值:“2019-12-22” input.valueAsNumber:157697280000 input.valueAsDate:“2019年12月21日星期六16:00:00 GMT-0800(太平洋标准时间)” 这个结果日期对象似乎是错误的 当浏览器返回值时,它将用户输入视为通用时间 因此,日期对象的utc表示形式与输入显示给用户的内容相同 input.valueAsDate.getUTCDate()返回用户输入的22 input

用户输入的日期输入
2019-12-22
给出以下值:

  • 输入值
    “2019-12-22”
  • input.valueAsNumber
    157697280000
  • input.valueAsDate
    “2019年12月21日星期六16:00:00 GMT-0800(太平洋标准时间)”
    • 这个结果日期对象似乎是错误的
    • 当浏览器返回值时,它将用户输入视为通用时间
    • 因此,日期对象的utc表示形式与输入显示给用户的内容相同
    • input.valueAsDate.getUTCDate()
      返回用户输入的
      22
    • input.valueAsDate.getDate()
      返回
      21
      ,而不是用户输入的内容
    • 因此,我们得出结论,日期输入显示并接受utc时间,而不是本地时间
我们希望结果
date.toString()
显示与日期输入中原始用户输入相同的结果


我们如何允许用户与本地时间交互,然后在脚本中获得正确的日期对象?

由于日期/时间输入元素接受用户输入为UTC时间,但我们希望接受本地时间,因此我们必须手动补偿用户计算机上配置的本地时区偏移量

因此,我们接受输入值作为一个数字,但在使用它创建日期对象之前,先用时区偏移量对其进行偏移

// ascertain the timezone offset
const timeOffset = (new Date()).getTimezoneOffset() * 60 * 1000

// compensate for the weirdness
const milliseconds = input.valueAsNumber + timeOffset

// make a real date object
const date = new Date(milliseconds)

当通过
toString()
toLocaleDateString()
向用户显示结果日期对象时,该对象将与用户最初输入的时间相同

由于日期/时间输入元素接受用户输入为UTC时间,但我们希望接受本地时间,因此我们必须手动补偿用户计算机上配置的本地时区偏移量

因此,我们接受输入值作为一个数字,但在使用它创建日期对象之前,先用时区偏移量对其进行偏移

// ascertain the timezone offset
const timeOffset = (new Date()).getTimezoneOffset() * 60 * 1000

// compensate for the weirdness
const milliseconds = input.valueAsNumber + timeOffset

// make a real date object
const date = new Date(milliseconds)

当通过
toString()
toLocaleDateString()
向用户显示结果日期对象时,该对象将与用户最初输入的时间相同

这一问题是由TC-39决定将日期–仅ISO 8601格式的时间戳视为UTC引起的,而与ISO 8601一致并将其视为本地时间戳则更符合逻辑。看

简单的解决方案是手动解析字符串,在最近将YYYY-MM-DD解析为本地之前,不要使用内置解析器作为至少一个当前实现。另外,不要使用当前时区偏移来调整时间值,因为这不允许偏移的历史更改或可能的夏令时更改

//将YYYY-MM-DD格式的时间戳解析为本地
函数parseISOLocal(s){
设[y,m,d]=s.split(/\d/);
返回新日期(y,-m,d);
}
//将日期格式化为YYYY-MM-DD本地
函数格式化本地(d){

设z=n=>(n此问题是由TC-39决定将日期–仅ISO 8601格式的时间戳视为UTC引起的,此时与ISO 8601一致并将其视为本地时间戳更符合逻辑。请参阅

简单的解决方案是手动解析字符串,在最近将YYYY-MM-DD解析为本地之前,不要使用内置解析器作为至少一个当前实现。此外,不要使用当前时区偏移来调整时间值,因为这不允许偏移量的历史变化或可能的夏令时变化。

//将YYYY-MM-DD格式的时间戳解析为本地
函数parseISOLocal(s){
设[y,m,d]=s.split(/\d/);
返回新日期(y,-m,d);
}
//将日期格式化为YYYY-MM-DD本地
函数格式化本地(d){

设z=n=>(我认为您混淆了内部日期状态及其
toString()
方法返回的表示形式。只需使用
input.valueAsDate.toLocaleDateString()即可
并且它应该与用户输入的内容相匹配。嘿,谢谢您的光临!不幸的是:不,否定:这不是真的。刚刚在实验中验证过,当用户输入
2019-12-22
时,您对
input.valueAsDate.toLocaleDateString()的建议实际上返回了
“21/12/2019”
——这与用户输入的不匹配——假设日期输入接受本地时间,然后返回一个本地输出匹配的日期对象,这是错误的——我知道,这很令人困惑,唯一的解决方法是手动补偿时间偏移奇怪的是,这在Firefox中很好,但在Chrome中却不行(我假设您正在使用)。@str--没人,我刚刚在firefox中复制了这个:
input.valueAsDate.toLocaleDateString()
返回
“2019年12月21日”
--我们之间可能存在一些不同的浏览器配置吗?当然是我们之间的时区差异,您的时区是什么?也许您的时区偏移量不足以显示一天中的差异——因此,对于我来说,在整个示例中使用时间输入可能更明智,如这个问题会对不在格林威治的任何人重现:)我将我的计算机的时区设置为您的(PST),以验证Firefox和Chrome的行为。他们没有为我返回相同的内容。我认为您混淆了内部日期状态及其
toString()返回的表示
方法。只需使用
input.valueAsDate.toLocaleDateString()
,它应该与用户输入的内容相匹配。嘿,谢谢您的光临!不幸的是:不,否定:这不是真的。刚刚在实验中验证,当用户输入
2019-12-22
时,您对
input.valueAsDate.toLocaleDateString()的建议
实际返回
“21/12/2019”
——与用户输入的内容不匹配——t