2016-06-19 76 views
0

計算UTC等同於昨天當地時間敲我的腦袋上這個簡單的日期邏輯問題:日期邏輯謎題:在上午8點

我知道相對於UTC用戶的時區偏移。

我的服務器是UTC。它知道現在的時間。

如何計算UTC當天上午8點的當地時間?在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

我認爲這應該是一個算術問題。邏輯部分在哪裏? – Mai

+0

邏輯部分是,我不知道它是邏輯問題還是算術問題。本地和UTC之間的計算讓我感到困惑。 – metalaureate

+0

你可以添加一個例子嗎?如果當前UTC時間爲「2016-01-10 0800」,應該輸出什麼? – Rahul

回答

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(); 
+0

完美。我不知道有'startOf'方法可用!真棒! – metalaureate

+0

由於以下幾個原因,此代碼無法處理DST轉換,因此不適合使用Moment.js進行此計算。如果今天的偏移量是-7,並且由於DST,昨天的偏移量是-8,則此代碼將不起作用。另外,如果時鐘在凌晨2點「向前跳躍」,那麼加上8小時將在上午9點降落。 –

+0

OP有偏移量,所以我認爲他會有正確的偏移量(包括適用的DST)。我的理解不正確?如果不是,請幫助我將其更改爲DST知道。我應該使用時區嗎?感謝您的澄清。 – Veeram

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點。

聽起來好像您的代碼正在服務器上的節點中運行。如果在瀏覽器中運行,瀏覽器知道用戶的時區規則,你可以使用下面的代碼昨天上午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

+0

我認爲一個簡單的'new Date()。getTimezoneOffset()'會考慮時區和DST。爲什麼不可能? – Mai

+0

因爲這是僅在特定時間點的偏移量。 'new Date()'給出了當前的日期和時間,所以'new Date()。getTimezoneOffset()'給出* current * offset。 –

相關問題