Как получить метку времени UTC в JavaScript?



при написании веб-приложения, имеет смысл хранить (на стороне сервера) все даты в БД в виде временных меток UTC.



Я был удивлен, когда заметил, что вы не могли изначально сделать много с точки зрения манипуляции часовым поясом в JavaScript.



Я немного расширил объект даты. Имеет ли эта функция смысл? В принципе, каждый раз, когда я отправляю что-либо на сервер, это будет временная метка, отформатированная с помощью этой функции...



вы можете видите здесь какие-то серьезные проблемы? Или, может быть, решение под другим углом?



Date.prototype.getUTCTime = function(){ 
return new Date(
this.getUTCFullYear(),
this.getUTCMonth(),
this.getUTCDate(),
this.getUTCHours(),
this.getUTCMinutes(),
this.getUTCSeconds()
).getTime();
}


это просто кажется мне немного запутанным. И я тоже не уверен в производительности.

819   15  

15 ответов:

  1. даты, построенные таким образом, используют местный часовой пояс, что делает построенную дату неправильной. Чтобы установить часовой пояс определенного объекта даты, необходимо построить его из строки даты, которая включает часовой пояс. (У меня были проблемы с тем, чтобы работать в старом браузере Android.)

  2. отметим, что getTime() возвращает миллисекунды, а не простая секунд.

для метки времени UTC / Unix необходимо следующее достаточно:

Math.floor((new Date()).getTime() / 1000)

он будет учитывать текущее смещение часового пояса в результате. Для строкового представления, Дэвид Эллис' ответ работает.

уточнения:

new Date(Y, M, D, h, m, s)

этот вход обрабатывается как местного времени. Если время UTC передается, результаты будут отличаться. Обратите внимание (я в GMT +02: 00 прямо сейчас, и это 07: 50):

> var d1 = new Date();
> d1.toUTCString();
"Sun, 18 Mar 2012 05:50:34 GMT" // two hours less than my local time
> Math.floor(d1.getTime()/ 1000)
1332049834 

> var d2 = new Date( d1.getUTCFullYear(), d1.getUTCMonth(), d1.getUTCDate(), d1.getUTCHours(), d1.getUTCMinutes(), d1.getUTCSeconds() );
> d2.toUTCString();
"Sun, 18 Mar 2012 03:50:34 GMT" // four hours less than my local time, and two hours less than the original time - because my GMT+2 input was interpreted as GMT+0!
> Math.floor(d2.getTime()/ 1000)
1332042634

также обратите внимание, что getUTCDate() не может быть заменен getUTCDay(). Это потому что getUTCDate() возвращает день месяца, а getUTCDay() возвращает день недели.

вы также можете сделать это с помощью getTimezoneOffset и getTime,

x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;

console.log("UTCseconds", UTCseconds)

да, вам не нужно делать; если я правильно вас понял, вы просто хотите toUTCString метод.

var UTCstring = (new Date()).toUTCString();

console.log('UTCstring', UTCstring);
  

однако помните, что значения даты, которые вы получаете, основаны на часах машины клиента, а не на вашем сервере. Если вам нужны точные значения для этих дат (например, чтобы правильно заказать когда то или иное действие было сделано относительно действий другого пользователя), вы не могу полагайтесь на стороне клиента библиотека дат, в любом случае, и вам нужно рассчитать даты на стороне сервера на основе того, когда клиент связался с вами.

Помните также, что в основном весь ваш клиентский код может быть изменен клиентом, и вместо этого возвращаются вредоносные значения, вы можете гарантировать только код на стороне сервера-относиться к клиентской стороне как к возможному злоумышленнику.

вам вообще не нужно делать много "манипуляции часового пояса" на стороне клиента. Как правило я стараюсь хранить и работать с датами UTC, в виде ticks или "количество миллисекунд с полуночи 1 января 1970 года."Это действительно упрощает хранение, сортировку, расчет смещений и, прежде всего, избавляет вас от головной боли настроек "летнее время". Вот немного кода JavaScript, который я использую.

чтобы получить текущий UTC время:

function getCurrentTimeUTC()
{
    //RETURN:
    //      = number of milliseconds between current UTC time and midnight of January 1, 1970
    var tmLoc = new Date();
    //The offset is in minutes -- convert it to ms
    return tmLoc.getTime() + tmLoc.getTimezoneOffset() * 60000;
}

тогда вам обычно нужно форматировать дату / время для конечного пользователя для их local часовой пояс и формат. Ниже приведены все сложности форматов даты и времени на клиентском компьютере:

function formatDateTimeFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted date/time
    return new Date(nTicks).toLocaleString();
}

function formatDateFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted date
    return new Date(nTicks).toLocaleDateString();
}

function formatTimeFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted time
    return new Date(nTicks).toLocaleTimeString();
}

Итак, следующий пример:

var ticks = getCurrentTimeUTC();  //Or get it from the server

var __s = "ticks=" + ticks + 
    ", DateTime=" + formatDateTimeFromTicks(ticks) +
    ", Date=" + formatDateFromTicks(ticks) +
    ", Time=" + formatTimeFromTicks(ticks);

document.write("<span>" + __s + "</span>");

возвращает следующее (Для моего английского языка США):

тики=1409103400661, DateTime=8/26/2014 6: 36: 40 PM, Date=8/26/2014, Время=6:36:40 ПМ

Я на самом деле думаю, что значения даты в js намного лучше, чем говорят объекты C# DateTime. Объекты C# DateTime имеют свойство Kind, но не имеют строгого базового часового пояса как такового, и преобразования часовых поясов трудно отслеживать, если вы конвертируете между двумя не UTC и не локальными временами. В js все значения даты имеют базовое значение UTC, которое передается и известно независимо от преобразования offest или часового пояса, которое вы делаете. Моя самая большая жалоба на объект даты-это количество неопределенного поведения, которое разработчики браузера выбрали для включения, что может запутать людей, которые атакуют даты в js методом проб и ошибок, чем чтение спецификации. Используя что-то вроде iso8601.js решает это изменяющееся поведение, определяя единственную реализацию объекта Date.

по умолчанию в спецификации говорится, что вы можете создавать даты с расширенным форматом даты ISO 8601, например

var someDate = new Date('2010-12-12T12:00Z');

таким образом, вы можете определить точное время UTC таким образом.

когда вы хотите передать значение даты обратно на сервер, который вы бы назвали

someDate.toISOString();

или если вы предпочитаете работать с миллисекундной меткой времени (количество миллисекунд с 1 января 1970 UTC)

someDate.getTime();

ISO 8601 является стандартом. Вы не можете быть смущены тем, что означает строка даты, если вы включаете смещение даты. Что это значит для вас как разработчика, так это то, что вы никогда не придется иметь дело с преобразованиями местного времени самостоятельно. Значения местного времени существуют чисто в интересах пользователя, и значения даты по умолчанию отображаются в их локальное время. Все манипуляции с локальным временем позволяют вам отображать что-то разумное для пользователя и конвертировать строки из пользовательского ввода. Это хорошая практика для преобразования в UTC, как только вы можете, и объект даты js делает это довольно тривиальным.

С другой стороны, не так много возможностей для принуждения часового пояса или локали для клиента (что я знаю), что может раздражать для конкретного веб-сайта настройки, но я думаю, что причина этого заключается в том, что это Конфигурация пользователя, которую нельзя трогать.

короче говоря, причина, по которой не так много родной поддержки для манипуляций с часовыми поясами, заключается в том, что вы просто не хотите этого делать.

самый простой способ получения времени UTC в обычном формате заключается в следующем:

new Date().toISOString()
"2016-06-03T23:15:33.008Z"

Я использую следующий:

Date.prototype.getUTCTime = function(){ 
  return this.getTime()-(this.getTimezoneOffset()*60000); 
};

после определения этого метода вы можете сделать:

var utcTime = new Date().getUTCTime();

если вы хотите один лайнер на UTC Unix Timestamp может быть создан в JavaScript как:

var currentUnixTimestap = ~~(+new Date() / 1000);

при этом будет учитываться часовой пояс системы. Это в основном время, прошедшее в секундах с эпохи.

как работает:

  • создать объект даты:new Date().
  • конвертировать в метку времени, добавив unary + перед созданием объекта преобразовать его в timestamp integer. :+new Date().
  • преобразовать от миллисекунд до секунд:+new Date() / 1000
  • использовать двойной Тильды чтобы округлить значение до целого числа. :~~(+new Date())

Я думаю, что это лучшее решение

// UTC milliseconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()

// UTC seconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()/1000|0

С new Date().toUTCString()возвращает строку типа "Wed, 11 Oct 2017 09:24:41 GMT" вы можете нарезать последние 3 символа и передать нарезанный строку new Date():

new Date()
// Wed Oct 11 2017 11:34:33 GMT+0200 (CEST)

new Date(new Date().toUTCString().slice(0, -3))
// Wed Oct 11 2017 09:34:33 GMT+0200 (CEST)

изменить: приведенный ниже код не работает. Я всегда предполагал, что новая дата().getTime () возвращает количество секунд с 1 января 1970 года в текущем часовом поясе. Это не так: getTime () возвращает количество секунд в формате UTC. Итак, приведенный ниже код делает грубую перенастройку. Всем спасибо!]

прежде всего, спасибо за ваши фантастические выводы. Я думаю, что мой вопрос имел неправильное название... это должно было быть "получить временную метку UTC Unix для существующего дата."

Итак, если у меня есть объект даты:

var d = new Date(2009,01,31)

Я был после функции, которая скажет мне "UTC Unix Timestamp".

эта функция, кажется, реальный трюк:

Date.prototype.getUTCUnixTime =  function (){
  return Math.floor( new Date(
    this.getUTCFullYear(),
    this.getUTCMonth(),
    this.getUTCDate(),
    this.getUTCHours(),
    this.getUTCMinutes(), 
    this.getUTCSeconds()
  ).getTime() / 1000); 
}

обратите внимание, что он работает на "это" это означает, что я могу сделать:

var n = new Date(2008,10,10)
...
...

n.getUTCUnixTime();

и получить количество секунд с 1 января 1970 года в Unix времени. Верно?

это немного безумно, для меня, что Javascript хранит все в UTC раз, но потом чтобы получить этот номер, мне нужно создать новый объект даты, передающий отдельные геттеры UTC, а затем, наконец, вызвать getTime() для этого...

Merc.

Я поражен тем, насколько сложным стал этот вопрос.

все они идентичны, и их целочисленные значения все = = = эпоха времени: D

console.log((new Date()).getTime() / 1000, new Date().valueOf() / 1000, (new Date() - new Date().getTimezoneOffset() * 60 * 1000) / 1000);

Не верьте мне, проверка: http://www.epochconverter.com/

Я хочу, чтобы ясно, что новая дата().getTime () фактически возвращает значение UTC, поэтому это действительно полезный способ хранения и управления датами таким образом, который является агностическим для локализованного времени.

другими словами, Не беспокойтесь обо всех функциях UTC javascript. Вместо этого просто используйте дату.метод getTime.)(

подробнее об объяснении здесь: если javascript "(новая дата ()).getTime () " выполняется из 2 разных часовых поясов.

Я думаю, что это то, что вы ожидаете...

var currTimestamp = Date.now(), //1482905176396
    utcDateString = (new Date(currTimestamp)).toUTCString(); //"Wed, 28 Dec 2016 06:06:50 GMT"

теперь

new Date(utcDateString).getTime(); //This will give you UTC Timestamp in JavaScript

возвращает метку времени в формате UTC:

var utc = new Date(new Date().toUTCString()).getTime();

Comments

    Ничего не найдено.