【问题标题】:Store date as if they were entered in a specific timezone存储日期,就好像它们是在特定时区中输入的一样
【发布时间】:2019-04-29 20:02:16
【问题描述】:

我正在使用 Moment。我需要用户输入一个日期,并确保该日期始终是澳大利亚/珀斯的时间,无论浏览器设置为什么。 例如,假设计算机设置为悉尼时间(现在是 +3,但在冬天是 +2)。我希望用户输入日期/时间,并确保该日期/时间存储为珀斯的时间。

请注意,可视化正确的日期不是问题(moment.tz)。我担心的是创建日期对象需要提供时间,并迫使浏览器假装它们在那个时区。

无论夏令时等情况如何,我都需要它来工作。

更新:这就是我想要实现的目标:

// MY CURRENT TIMEZONE IS SYDNEY, CURRENTLY PERTH + 3 BUT +2 IN SUMMER
// IN PERTH IT's 10:11AM, and *THAT* is the time I am interested in 
// storing, not 13:11:58
var d = new Date()
// => Wed Nov 28 2018 13:11:58 GMT+1100 (Australian Eastern Daylight Time)

// NOTE: the date 13:11:58 SYDNEY time. I don't want this.
// I MUST pretend that users entered the date with their timezone
// is in Perth
// So...

// Create a date string that exclude original timezone and includes new timezone
perthDateString = moment(new Date()).format('YYYY-MM-DDTHH:MM:ss') + '+0800'
// => "2018-11-28T13:11:58+0800"

// Make a new date object using the tinkered date string 
var newD = new Date(perthDateString)

// Display the date. Note: the time is "wrong" (since it displays
// a time that is 3 hours ahead), but it's actually the correct
// answer since 'd' is meant to be Perth time in the first place
newD
// => Wed Nov 28 2018 16:11:58 GMT+1100 (Australian Eastern Daylight Time)

// Display the date as the Perth time
moment.tz(newD, 'Australia/Perth').toString()
// => "Wed Nov 28 2018 13:11:58 GMT+0800"

但是:

  • perthDateString = moment(new Date()).format('YYYY-MM-DDTHH:MM:ss') + '+0800',我想指定Australia/Perth,而不是'+0800'

  • 我对通过截断/连接字符串来处理日期感到不安

  • 我想知道是否每个浏览器都能够解析 .format('YYYY-MM-DDTHH:MM:ss') + '+0800' 返回的日期,或者我是否会有惊喜 - 特别是当/如果我有解决方案以便我使用 Australia/Perth 而不是

【问题讨论】:

  • developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 。 getTime() 始终使用 UTC 表示时间。例如,一个时区的客户端浏览器,getTime() 将与任何其他时区的客户端浏览器相同。
  • 恕我直言,您真的应该考虑仅在 UTC 中使用时间(当然显示除外)。当然,如果您需要,也可以存储时区,但对于州际(或国际)时间比较,除 UTC 之外的任何时间都将成为您自己的支持
  • @Kingsley 已经是这样了。我将日期作为 UTC 存储在数据库中。但是,如果悉尼的用户写12:30,我实际上想存储15:30。我正在尝试做的,是一种迫使客户进入时间的方式,就好像他们在珀斯一样
  • @RenaissanceProgrammer 我不担心显示(见帖子),我担心存储
  • 嗯。我们中的一个人很困惑。如果您以 UTC 格式存储时间,那么您不会存储悉尼时间(例如,12:30)或珀斯时间(等效为 9:30 - 不是 15:30,如您所指出的)。显示时间时,存储的 UTC 时间 (1:30) 可以转换为您想要的任何其他时区 - 您已经知道。那么,如果你已经存储了UTC时间,并且你已经知道在需要显示时间的时候需要转换到合适的时区,那么你真的有问题吗?

标签: javascript date timezone momentjs


【解决方案1】:

如果您在世界任何地方(例如,悉尼或东京),并且当地时间是“12:30”,但您想要存储相同的时间(“12:30”),就像你在珀斯——你可以使用moment-timezone 包和moment

例如,这个 sn-p 会给你一个moment 代表珀斯的“12:30”:

let x = moment.tz('2019-01-01T12:30:00', 'Australia/Perth')
console.log(x.format());  // Show that it is 12:30 in Perth time
console.log(new Date(x)); // Generate Date for that time
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="http://momentjs.com/downloads/moment-timezone-with-data.js"></script>

【讨论】:

  • 是的,是的,是的。是的,是的,谢谢!
  • 难怪你有 38.1k 点... 琐事:Tokio 几乎和珀斯在同一个时区 eheheheh :D
  • 额外问题——如果可以的话。如果我有d="2018-01-30"t="18:30" 并想像在珀斯一样创建这个时间怎么办?目前我正在做var d = moment.tz(${d} ${t}, 'Australia/Perth') 但感觉很老套和错误...帮助?
  • 试试:moment.tz(d, 'Australia/Perth').add(moment.duration(t));
猜你喜欢
  • 2017-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多