首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >js,获取不同时区午夜的本地时间

js,获取不同时区午夜的本地时间
EN

Stack Overflow用户
提问于 2018-07-10 18:49:59
回答 2查看 1.1K关注 0票数 0

我想计算一下洛杉矶当地时间是第二天24:00。这样做的目的是在洛杉矶的下一个午夜之前设置一个cookie。

我已经使用了moment和moment时区,然而,我不能证明单个函数的构建大小的开销是合理的。

这是我正在使用的,但我被困在将洛杉矶午夜的时间转换回本地时间,因为当我转换回来时,它是在当前时间之前。我不认为在反向操作时convertToOtherTimezone函数会有问题,但我不太确定还可以探索什么。

任何帮助都是非常感谢的。

代码语言:javascript
复制
const convertToOtherTimezone = (date, from, to) => {
  const utc = date.getTime() + (3600000 * from)
  return new Date(utc + (3600000 * to))
}

console.log(
  'native local time in LA',
  new Date().toLocaleString('en-US', { timeZone: 'America/Los_Angeles' })
)

const LA_OFFSET = -7
// I'm using the AEST timezone -10
const LOCAL_OFFSET = new Date().getTimezoneOffset() / 60

const midnightInLA = (localOffset) => {
  // get the current time in LA
  const la = convertToOtherTimezone(new Date(), localOffset, LA_OFFSET)
  console.log('current time in LA', la)
  // set date to midnight in LA's timezone
  la.setHours(24,0,0,0)
  console.log('next midnight in LA', la)
  // convert back to local time
  return convertToOtherTimezone(la, LA_OFFSET, localOffset)
  // Ulias Hunka gave the correct answer, but deleted his post.
  // reverse the offsets
  return convertToOtherTimezone(la, LA_OFFSET * -1, localOffset * -1)
}

console.log(
  'la midnight in local time',
  midnightInLA(LOCAL_OFFSET)
)
代码语言:javascript
复制
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>

EN

回答 2

Stack Overflow用户

发布于 2018-07-11 21:32:21

洛杉矶的标准时间是UTC-0800。它在3月份的第二个星期日凌晨2点转换为夏令时(DST),此时偏移量更改为UTC-0700。它在11月的第一个星期日凌晨2点(美国夏令时)结束。

这些规则很可能会持续一段时间,如果您只对当前日期感兴趣,则可以使用这些规则,直到它们发生变化。您可以计算出给定日期和时间的偏移量,然后为洛杉矶的下一个午夜创建一个日期。我希望你把这些信息放在问题里,而不是放在评论里。见下文。

代码语言:javascript
复制
/**
 *  Calculate the offset in LA for the given date and time.
 *  LA DST starts on the second Sunday in March at
 *  10:00 UTC. After that, the offset is UTC-0700
 *  LA DST ends on the first Sunday in November at 09:00
 *  UTC. After that the offset is UTC-0800
 *
 *  @param {Date} date - date object
 *  @returns (boolean} true if DST is being observed
 */
function getLAOffset(date) {
  // Get DST start in UTC
  var start = new Date(Date.UTC(date.getUTCFullYear(), 2, 1, 10));
  start.setUTCDate(start.getUTCDate() + (7-start.getUTCDay())%7 + 7);
  // Get DST end in UTC
  var end = new Date(Date.UTC(date.getUTCFullYear(), 10, 1, 9));
  end.setUTCDate(end.getUTCDate() + (7-end.getUTCDay())%7);
  return (date >= start && date < end)? -7 : -8;
}

/** Return a Date object set to midnight in LA
 *  for the next midnight after the given date.
 *  Offset comes from getLAOffset
 *
 *  @param {Date} date to use for local date values
 *  @returns {Date} set to midnight in LA
 */
function getLAMidnight(date) {
  var d = new Date(+date);
  
  // Get offset. If hour is before offset, set to offset
  // If hour is after offset, set to offset tomorrow
  // Re-check offset and adjust if necessary
  var offset = getLAOffset(d);
  var midLA = d.setUTCHours(-offset, 0, 0, 0);
  if (d < date) d.setUTCDate(d.getUTCDate() + 1);
  d.setUTCHours(-getLAOffset(d));
  return d;
}

// Local date and time for midnight LA tomorrow:
[new Date(2018,0, 1),     //  1 Jan 2018
 new Date(2018,2,11),     // 11 Mar 2018
 new Date(2018,2,11, 12), // 11 Mar 2018, noon
 new Date(2018,2,12),     // 12 Mar 2018
 new Date(2018,5, 1),     //  1 Jun 2018
 new Date(2018,10,4),     //  4 Nov 2018
 new Date(2018,11,1),     //  1 Dec 2018
 new Date()               // Current
].forEach(function(date) {
  console.log('Local date       : ' + date.toString() +
            '\nNext LA midnight : ' + getLAMidnight(date).toString());
});

票数 1
EN

Stack Overflow用户

发布于 2018-07-10 23:46:39

我相信您问题中的代码片段非常接近,但似乎您在错误的方向上添加了偏移量。

您可能会遇到夏令时的问题-例如,洛杉矶在夏季的几个月是UTC-7h,但通常是UTC-8h。如果您不想使用moment.js,那么我能想到的惟一选择就是解析当时地区格式的字符串。

这不是最健壮的方法,仅适用于en-US格式的时间。根据浏览器的不同,America/Los_Angeles时区也可能不可用。

代码语言:javascript
复制
let now = new Date()

// Get the current time in LA using string matching to enable the offset to be calculated
// This allows for daylight savings to be considered
// Caution the LocaleTimeString is en-US formatted. Take care if using a different locale
let timeInLA = now.toLocaleTimeString('en-US', { timeZone: 'America/Los_Angeles' })
  .match(/([0-1]?[0-9])\:([0-5]?[0-9])\:[0-5]?[0-9]\s(AM|PM)/)
  // trim first element of match
  .slice(1)
   // take account of AM/PM and convert values to integers
  .map( (e,i,a) => i==0 && a[3] =='PM' ? +e+12 : +e)
  // trim AM/PM
  .slice(0,-1)
  
// positive values mean local time is ahead of LA
let offsets = [now.getHours(),now.getMinutes()].map((e,i) => e-timeInLA[i])

// sum up hours and minutes to get totalOffset and convert to ms
let totalOffsetMS = (offsets[0]*3600 + offsets[1]*60)*1000

// local midnight Tomorrow - add 24 hours and zero other values
let localMidnightTomorrow = new Date(+now.setHours(24,0,0,0))

// LA midnight will happen at the local midnight time with the offset added
let localTimeWhenMidnightInLA = new Date(+localMidnightTomorrow + totalOffsetMS)

console.log(`It will be "${localTimeWhenMidnightInLA.toDateString()} ${localTimeWhenMidnightInLA.toTimeString()}" in your location when it is midnight in LA tomorrow`)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51263321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档