对这个简单的日期逻辑问题大加赞赏:
我知道用户相对于UTC的时区偏移。
我的服务器是UTC。它知道现在的时间。
如何计算当天上午8点的'以及
的UTC当量时间在JS中,我试图这样做,但似乎不太有用。
var yesterday_am=moment(moment(new Date()).subtract(24,'hour')).format('YYYY-MM-DD'); // same local time previous day;
// when is 8am local time in utc?
var am=8 - (user.tz_offset/60);
if (am<0) { yesterday_am=moment(yesterday_am).subtract(Math.abs(am), 'hour')};
if (am>0) { yesterday_am=moment(yesterday_am).add(am, 'hour')};
例如,如果UTC为2016-01-10 0235
且本地时间为-7小时,则会输出2016-1-09 1500
(本地时间早上8点)。
答案 0 :(得分:2)
您尝试执行的逻辑是不可能的。在不知道用户的实际时区的情况下,您无法知道当地时间“昨天上午8点”的UTC等价物。夏令时转换可能使昨天的偏移量与今天的偏移量不同。有关详细信息,请参阅time zone tag wiki,尤其是时区!=偏移部分。
如果您确实知道用户的时区,则可以使用Moment.js的moment timezone附加库执行此计算。代码如下:
moment().tz('America/Los_Angeles').subtract(1, 'day')
.set({hours:8, minutes:0, seconds:0, milliseconds:0}).utc()
打破这一点,这是有道理的,我们正在做以下事情:
moment() //get the current time
.tz('America/Los_Angeles') //put the moment in the Los Angeles time zone
//the Los Angeles time zone is one of several that are UTC-7 right now
.subtract(1, 'day') //go to yesterday
.set({hours:8, minutes:0, seconds:0, milliseconds:0}) //set the time to exactly 8 am
.utc() //convert back to UTC
不要在当天开始增加8小时。如果那天的时钟向前跳,那么将是上午9点,如果他们'倒退'则是早上7点。
听起来您的代码在服务器上的Node中运行。如果它在浏览器中运行,则浏览器知道用户的时区规则,您可以使用以下代码在昨天上午8点获取时间:
moment().subtract(1, 'day').set({hours:8, minutes:0, seconds:0, milliseconds:0}).utc()
此代码不需要添加时刻,因为浏览器知道用户当地时间的时区规则。
如果您需要获取用户的时区,则可以选择一些选项。最可靠的是使用内置于地图中的时区选择器让用户选择。其中有一些漂浮在互联网上。
如果您不想这样做,可以使用moment.tz.guess()
功能让片刻时区使用某些启发式方法对用户的时区进行有根据的猜测。这个功能很好,但由于浏览器的限制,不可能100%准确。
有关在JavaScript中处理日期,时间和时区的大量信息,您可以在几个月前尝试this talk I did at JavaScript MN。
此外,您可能希望this really excellent Pluralsight course by Matt Johnson。
答案 1 :(得分:0)
此代码不支持DST (如果您尚未根据以下评论弄清楚)。谢谢玛吉。请参考Maggie的完整答案。
你可以做这样的事情
var localTime = moment.utc("2016-06-19").utcOffset('-07:00');
var utcAt8PrevDay = moment(localTime).subtract(1,'days').startOf('day').add(8, 'hour').utc();