Converter hora de data UTC em hora local

336

No servidor, recebo uma variável datetime neste formato: 6/29/2011 4:52:48 PMe é no horário UTC. Quero convertê-lo para o horário do navegador do usuário atual usando JavaScript.

Como isso pode ser feito usando JavaScript ou jQuery?

Amr Elgarhy
fonte
11
Seja cuidadoso. Esse é um formato de data estranho, portanto, especifique-o em qualquer solução usada. Se possível, peça ao servidor para enviar a data no formato ISO.
Michael Scheper

Respostas:

402

Anexe 'UTC' à string antes de convertê-la em uma data em javascript:

var date = new Date('6/29/2011 4:52:48 PM UTC');
date.toString() // "Wed Jun 29 2011 09:52:48 GMT-0700 (PDT)"
banho digital
fonte
5
função localizeDateStr (date_to_convert_str) {var date_to_convert = nova data (date_to_convert_str); var local_date = nova data (); date_to_convert.setHours (date_to_convert.getHours () + local_date.getTimezoneOffset ()); return date_to_convert.toString (); }
mate
4
@ Matt compensar retornos minutos, não em horas, é preciso dividir por 60
Bladefist
50
Isso pressupõe que a parte da data da sequência esteja seguindo o padrão dos EUA, mm / dd / AAAA, o que obviamente não é o caso na Europa e em outras partes do mundo.
AsGoodAsItGets
7
@digitalbath Funciona no Chrome, mas não no Firefox.
Ganesh Satpute
137

No meu ponto de vista, os servidores sempre devem retornar, no caso geral, uma data e hora no formato ISO 8601 padronizado .

Mais informações aqui:

Nesse caso, o servidor retornaria, o '2011-06-29T16:52:48.000Z'que alimentaria diretamente o objeto JS Date.

var utcDate = '2011-06-29T16:52:48.000Z';  // ISO-8601 formatted date returned from server
var localDate = new Date(utcDate);

O localDatehorário será o local certo, o que, no meu caso, ocorreria duas horas depois (horário da Dinamarca).

Você realmente não precisa fazer toda essa análise, o que apenas complica as coisas, desde que seja consistente com o formato esperado do servidor.

Hulvej
fonte
11
como obter a data do formato iso? Estou recebendo data no formato UTC com o UTC anexado ao final #
Deepika
8
@ Colin que depende do idioma. Em C #, você pode formatar um DateTimeobjeto com o .toString("o")qual retorna uma seqüência de caracteres formatada ISO-8601, como mostrado acima. msdn.microsoft.com/en-us/library/zdtaw1bw(v=vs.110).aspx Em javascript é new Date().toISOString(). developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Hulvej
98

Esta é uma solução universal:

function convertUTCDateToLocalDate(date) {
    var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000);

    var offset = date.getTimezoneOffset() / 60;
    var hours = date.getHours();

    newDate.setHours(hours - offset);

    return newDate;   
}

Uso:

var date = convertUTCDateToLocalDate(new Date(date_string_you_received));

Exiba a data com base na configuração local do cliente:

date.toLocaleString();
Adorjan Princz
fonte
41
Não funciona com todos os fusos horários. Há uma boa razão pela qual getTimeZoneOffset está em minutos! geographylists.com/list20d.html
siukurnin
5
@siukurnin. Então, para gerenciar um fuso horário estranho, use newDate.setTime (date.getTime () + date.getTimezoneOffset () * 60 * 1000)
7500 Guillaume Gendre
18
newDate.setMinutes (date.getMinutes () - date.getTimezoneOffset ()) seria suficiente. Corrige também as horas
Lu55 23/10/2013
11
Certamente isso não pode funcionar para qualquer fuso horário que esteja a 30 minutos? Parece arredondar para horas inteiras.
NickG
2
Isso também não parece definir a data corretamente quando o turno do fuso horário cruza a meia-noite; possivelmente porque está usando setHours, o que não afeta a data?
Uniphonic:
37

Você deve obter o deslocamento (UTC) (em minutos) do cliente:

var offset = new Date().getTimezoneOffset();

E então faça a adição ou subtração correspondente ao tempo que você obtém do servidor.

Espero que isto ajude.

Nobita
fonte
2
E o horário de verão?
Rico
26

Para mim, as soluções acima não funcionaram.

Com o IE, a conversão de data e hora UTC para local é um pouco complicada. Para mim, a data e hora da API da web é '2018-02-15T05:37:26.007'e eu queria converter conforme o fuso horário local, então usei o código abaixo em JavaScript.

var createdDateTime = new Date('2018-02-15T05:37:26.007' + 'Z');
PramodB
fonte
21

Coloque esta função em sua cabeça:

<script type="text/javascript">
function localize(t)
{
  var d=new Date(t+" UTC");
  document.write(d.toString());
}
</script>

Em seguida, gere o seguinte para cada data no corpo da sua página:

<script type="text/javascript">localize("6/29/2011 4:52:48 PM");</script>

Para remover o GMT e o fuso horário, altere a seguinte linha:

document.write(d.toString().replace(/GMT.*/g,""));
Ben Bryant
fonte
20

Isso funciona para mim:

function convertUTCDateToLocalDate(date) {
    var newDate = new Date(date.getTime() - date.getTimezoneOffset()*60*1000);
    return newDate;   
}
Molp Burnbright
fonte
10

Depois de tentar alguns outros postados aqui sem bons resultados, isso pareceu funcionar para mim:

convertUTCDateToLocalDate: function (date) {
    return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(),  date.getHours(), date.getMinutes(), date.getSeconds()));
}

E isso funciona no sentido oposto, da Data Local ao UTC:

convertLocalDatetoUTCDate: function(date){
    return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),  date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
}
Uniphonic
fonte
11
Menos código para usar new Date(+date + date.getTimezoneOffset() * 6e4). ;-)
RobG 21/09
não funcionará, meu tempo no utc é "2020-04-02T11: 09: 00", então tentei isso em Cingapura, nova data (+ nova data ("2020-04-02T11: 09: 00") + nova data ( "2020-04-02T11: 09: 00"). GetTimezoneOffset () * 6e4), fornecendo hora errada
AhammadaliPK
isso funcionou, nova data ("2020-04-02T11: 09: 00" + 'Z');
AhammadaliPK
10

Adicione o fuso horário no final, neste caso 'UTC':

theDate = new Date( Date.parse('6/29/2011 4:52:48 PM UTC'));

depois disso, use as famílias de funções toLocale () * para exibir a data na localidade correta

theDate.toLocaleString();  // "6/29/2011, 9:52:48 AM"
theDate.toLocaleTimeString();  // "9:52:48 AM"
theDate.toLocaleDateString();  // "6/29/2011"
pabloa98
fonte
9

A resposta de Matt está ausente do fato de que o horário de verão pode ser diferente entre Date () e o horário que ele precisa converter - eis a minha solução:

    function ConvertUTCTimeToLocalTime(UTCDateString)
    {
        var convertdLocalTime = new Date(UTCDateString);

        var hourOffset = convertdLocalTime.getTimezoneOffset() / 60;

        convertdLocalTime.setHours( convertdLocalTime.getHours() + hourOffset ); 

        return convertdLocalTime;
    }

E os resultados no depurador:

UTCDateString: "2014-02-26T00:00:00"
convertdLocalTime: Wed Feb 26 2014 00:00:00 GMT-0800 (Pacific Standard Time)
MaurGi
fonte
9

Use isso para converter UTC e hora local e vice-versa.

//Covert datetime by GMT offset 
//If toUTC is true then return UTC time other wise return local time
function convertLocalDateToUTCDate(date, toUTC) {
    date = new Date(date);
    //Local time converted to UTC
    console.log("Time: " + date);
    var localOffset = date.getTimezoneOffset() * 60000;
    var localTime = date.getTime();
    if (toUTC) {
        date = localTime + localOffset;
    } else {
        date = localTime - localOffset;
    }
    date = new Date(date);
    console.log("Converted time: " + date);
    return date;
}
Mr. Polywhirl
fonte
3
o que aconteceu no horário de verão. Fuso horário CET
NovusMobile 11/11/2015
Veja a minha resposta @ stackoverflow.com/questions/6525538/…
Hulvej
9

Esta é uma solução simplificada com base na resposta do Adorjan Princ:

function convertUTCDateToLocalDate(date) {
    var newDate = new Date(date);
    newDate.setMinutes(date.getMinutes() - date.getTimezoneOffset());
    return newDate;
}

Uso:

var date = convertUTCDateToLocalDate(new Date(date_string_you_received));
huha
fonte
Por que isso foi rebaixado em 9 de outubro de 2017? Por favor, escreva um comentário para me ajudar a entender sua opinião.
huha
9

Caso você não se importe de usar moment.jse seu horário esteja no UTC, use o seguinte:

moment.utc('6/29/2011 4:52:48 PM').toDate();

se o seu tempo não estiver em utc, mas em qualquer outro local conhecido, use o seguinte:

moment('6/29/2011 4:52:48 PM', 'MM-DD-YYYY', 'fr').toDate();

se o seu horário já estiver no local, use o seguinte:

moment('6/29/2011 4:52:48 PM', 'MM-DD-YYYY');
adnan kamili
fonte
5

Para mim, o mais simples parecia usar

datetime.setUTCHours(datetime.getHours());
datetime.setUTCMinutes(datetime.getMinutes());

(eu pensei que a primeira linha poderia ser suficiente, mas há fusos horários que estão desativados em frações de horas)

mizuki nakeshu
fonte
Alguém tem algum problema com isso? Esta parece ser a melhor opção para mim. Peguei uma string UTC que tinha "(UTC)" no final dela, configurei-a como um objeto Date usando new Date('date string')e, em seguida, adicionei essas duas linhas e parece estar voltando com um horário baseado completamente no carimbo de data / hora UTC do servidor com ajustes feitos para corresponder à hora local do usuário. Eu precisa se preocupar com as fracções de-an-hour estranhas fusos horários também ... Não tenho certeza se ele mantém-se perfeitamente o tempo todo ...
tylerl
tentei muitas outras opções, nenhuma delas funcionou, mas isso está funcionando #
Sameera K
5

Uma sequência de datas JSON (serializada em C #) se parece com "2015-10-13T18: 58: 17".

Em angular, (seguindo Hulvej) faça um localdatefiltro:

myFilters.filter('localdate', function () {
    return function(input) {
        var date = new Date(input + '.000Z');
        return date;
    };
})

Em seguida, exiba a hora local como:

{{order.createDate | localdate | date : 'MMM d, y h:mm a' }}
James Howey
fonte
3

Usando o YYYY-MM-DD hh:mm:ssformato:

var date = new Date('2011-06-29T16:52:48+00:00');
date.toString() // "Wed Jun 29 2011 09:52:48 GMT-0700 (PDT)"

Para converter do YYYY-MM-DD hh:mm:ssformato, verifique se a sua data segue o formato ISO 8601 .

Year: 
    YYYY (eg 1997)    
Year and month: 
    YYYY-MM (eg 1997-07)
Complete date: 
    YYYY-MM-DD (eg 1997-07-16)
Complete date plus hours and minutes:
    YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)    
Complete date plus   hours, minutes and seconds:
    YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)    
Complete date plus hours, minutes, seconds and a decimal fraction of a second
    YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00) where:

YYYY = four-digit year
MM   = two-digit month (01=January, etc.)
DD   = two-digit day of month (01 through 31)
hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
mm   = two digits of minute (00 through 59)
ss   = two digits of second (00 through 59)
s    = one or more digits representing a decimal fraction of a second
TZD  = time zone designator (Z or +hh:mm or -hh:mm)

Coisas importantes a serem observadas

  1. Você deve separar a data e a hora com a T, um espaço não funcionará em alguns navegadores
  2. Você deve definir o fuso horário usando este formato +hh:mm, o uso de uma sequência de caracteres para um fuso horário (por exemplo: 'UTC') não funcionará em muitos navegadores. +hh:mmrepresenta o deslocamento do fuso horário UTC.
Gudradain
fonte
3

@Adorojan'sa resposta está quase correta. Mas a adição do deslocamento não está correta, pois o valor do deslocamento será negativo se a data do navegador estiver adiantada em relação ao GMT e vice-versa. Abaixo está a solução que eu vim com e está funcionando perfeitamente para mim:

// Input time in UTC
var inputInUtc = "6/29/2011 4:52:48";

var dateInUtc = new Date(Date.parse(inputInUtc+" UTC"));
//Print date in UTC time
document.write("Date in UTC : " + dateInUtc.toISOString()+"<br>");

var dateInLocalTz = convertUtcToLocalTz(dateInUtc);
//Print date in local time
document.write("Date in Local : " + dateInLocalTz.toISOString());

function convertUtcToLocalTz(dateInUtc) {
		//Convert to local timezone
		return new Date(dateInUtc.getTime() - dateInUtc.getTimezoneOffset()*60*1000);
}

Joe
fonte
3

Para mim, isso funciona bem

if (typeof date === "number") {
  time = new Date(date).toLocaleString();
  } else if (typeof date === "string"){
  time = new Date(`${date} UTC`).toLocaleString();
}
C.Lee
fonte
2

Eu respondendo a isso se alguém quiser uma função que mostre a hora convertida em um elemento de identificação específico e aplique o formato de data string aaaa-mm-dd aqui date1 é string e ids é a identificação do elemento que a hora será exibida.

function convertUTCDateToLocalDate(date1, ids) 
{
  var newDate = new Date();
  var ary = date1.split(" ");
  var ary2 = ary[0].split("-");
  var ary1 = ary[1].split(":");
  var month_short = Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
  newDate.setUTCHours(parseInt(ary1[0]));
  newDate.setUTCMinutes(ary1[1]);
  newDate.setUTCSeconds(ary1[2]);
  newDate.setUTCFullYear(ary2[0]);
  newDate.setUTCMonth(ary2[1]);
  newDate.setUTCDate(ary2[2]);
  ids = document.getElementById(ids);
  ids.innerHTML = " " + newDate.getDate() + "-" + month_short[newDate.getMonth() - 1] + "-" + newDate.getFullYear() + " " + newDate.getHours() + ":" + newDate.getMinutes() + ":" + newDate.getSeconds();
            }

Eu sei que a resposta já foi aceita, mas eu cheguei aqui porque o google e resolvi obtendo inspiração da resposta aceita, então eu queria apenas compartilhá-la se alguém precisar.

Nisarg Desai
fonte
1

Com base na resposta @digitalbath, aqui está uma pequena função para pegar o carimbo de data / hora UTC e exibir a hora local em um determinado elemento DOM (usando jQuery para esta última parte):

https://jsfiddle.net/moriz/6ktb4sv8/1/

<div id="eventTimestamp" class="timeStamp">
   </div>
   <script type="text/javascript">
   // Convert UTC timestamp to local time and display in specified DOM element
   function convertAndDisplayUTCtime(date,hour,minutes,elementID) {
    var eventDate = new Date(''+date+' '+hour+':'+minutes+':00 UTC');
    eventDate.toString();
    $('#'+elementID).html(eventDate);
   }
   convertAndDisplayUTCtime('06/03/2015',16,32,'eventTimestamp');
   </script>
Moriz
fonte
0

Eu escrevi um pequeno script que leva uma época do UTC e o converte no fuso horário do sistema do cliente e o retorna no formato d / m / YH: i: s (como a função de data do PHP):

getTimezoneDate = function ( e ) {

    function p(s) { return (s < 10) ? '0' + s : s; }        

    var t = new Date(0);
    t.setUTCSeconds(e);

    var d = p(t.getDate()), 
        m = p(t.getMonth()+1), 
        Y = p(t.getFullYear()),
        H = p(t.getHours()), 
        i = p(t.getMinutes()), 
        s = p(t.getSeconds());

    d =  [d, m, Y].join('/') + ' ' + [H, i, s].join(':');

    return d;

};
John Bell
fonte
0

Você pode usar momentjs , moment(date).format()sempre dará resultado na data local .

Bônus , você pode formatar da maneira que desejar. Por exemplo.

moment().format('MMMM Do YYYY, h:mm:ss a'); // September 14th 2018, 12:51:03 pm
moment().format('dddd');                    // Friday
moment().format("MMM Do YY"); 

Para mais detalhes, consulte o site Moment js

AConsumidor
fonte
0

Você pode fazer isso usando o arquivo moment.js .

É simples, você acabou de mencionar o local do fuso horário.

Exemplo: para converter seu horário e data para fuso horário da Ásia / Calcutá, basta mencionar o nome do local do fuso horário obtido a partir de moment.js

var UTCDateTime="Your date obtained from UTC";
var ISTleadTime=(moment.tz(UTCDateTime, "Africa/Abidjan")).tz("Asia/Kolkata").format('YYYY-MM-DD LT');

REvathY M
fonte
0

Eu criei uma função que converte todos os fusos horários em horário local.

Eu não usei getTimezoneOffset (), porque ele não retorna o valor de deslocamento adequado

Requisitos:

1. npm i moment-timezone

function utcToLocal(utcdateTime, tz) {
    var zone = moment.tz(tz).format("Z") // Actual zone value e:g +5:30
    var zoneValue = zone.replace(/[^0-9: ]/g, "") // Zone value without + - chars
    var operator = zone && zone.split("") && zone.split("")[0] === "-" ? "-" : "+" // operator for addition subtraction
    var localDateTime
    var hours = zoneValue.split(":")[0]
    var minutes = zoneValue.split(":")[1]
    if (operator === "-") {
        localDateTime = moment(utcdateTime).subtract(hours, "hours").subtract(minutes, "minutes").format("YYYY-MM-DD HH:mm:ss")
    } else if (operator) {
        localDateTime = moment(utcdateTime).add(hours, "hours").add(minutes, "minutes").format("YYYY-MM-DD HH:mm:ss")
    } else {
        localDateTime = "Invalid Timezone Operator"
    }
    return localDateTime
}

utcToLocal("2019-11-14 07:15:37", "Asia/Kolkata")

//Returns "2019-11-14 12:45:37"
Rohit Parte
fonte
0

No meu caso, tive que encontrar a diferença de datas em segundos. A data era uma string de data UTC, então eu a converti em um objeto de data local. Isto é o que eu fiz:

let utc1 = new Date();
let utc2 = null;
const dateForCompare = new Date(valueFromServer);
dateForCompare.setTime(dateForCompare.getTime() - dateForCompare.getTimezoneOffset() * 
 60000);
utc2 = dateForCompare;

const seconds = Math.floor(utc1 - utc2) / 1000;
Suraj Galande
fonte
-1
function getUTC(str) {
    var arr = str.split(/[- :]/);
    var utc = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]);
    utc.setTime(utc.getTime() - utc.getTimezoneOffset()*60*1000)
    return utc;
}

Para outras pessoas que visitam - use esta função para obter um objeto Data local a partir de uma string UTC, deve cuidar do horário de verão e trabalhará no IE, IPhone etc.

Dividimos a sequência (uma vez que a análise JS Date não é suportada em alguns navegadores). Obtemos diferença do UTC e subtraímos do horário UTC, o que nos dá a hora local. Como o deslocamento retornado é calculado com o horário de verão (corrija-me se eu estiver errado), ele ajustará esse tempo novamente na variável "utc". Finalmente, retorne o objeto de data.

Dapu
fonte
-1

Em Angular, usei a resposta de Ben desta maneira:

$scope.convert = function (thedate) {
    var tempstr = thedate.toString();
    var newstr = tempstr.toString().replace(/GMT.*/g, "");
    newstr = newstr + " UTC";
    return new Date(newstr);
};

Edit: Angular 1.3.0 adicionado suporte UTC ao filtro de datas, ainda não o usei, mas deve ser mais fácil, aqui está o formato:

{{ date_expression | date : format : timezone}}

API de data angular 1.4.3

Helzgate
fonte