Passing GTM 0 to local date

5

I want to pass a date that is in GTM0 to my local time, according to momentjs it's from this way , but I can not convert the date to my local time.

moment.locale('es');

let fecha = '2018-12-07 22:56:48';

let fecha_origin = moment(fecha).format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A');
console.log('Fecha original: ', fecha_origin);

let fecha_local = moment(fecha).utc().format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A');
console.log('Conversión: ', fecha_local);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>

Update 1:

My local time is supposed to be -5, but it is +5 when I do the conversion.

    
asked by Pablo Contreras 08.12.2018 в 03:32
source

4 answers

4

Let's first understand how dates work with moment.js, analyzing examples, but first:

moment.locale('es');

This only affects the language, that is, if Dec (ember) or Dec (December) is to be written, not at the time. Therefore we can dismiss it as a cause of problems

let fecha = '2018-12-07 22:56:48';

Define a moment in a standard format. But what time is it? Let's do some tests to prove it. I am in GMT + 1 (Spain):

let momento = moment();

console.log('sin formato', momento);
//sin formato "2018-12-14T16:49:56.834Z"

console.log('con formato', momento.format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A'));
//con formato 14 de Dec del 2018 a las 05:49:56 PM

We already see a difference: without format the time Zulú is used (that is why the final Z), whereas when using format, the Local Zone of the operating system of my machine is used.

Zulu time is the time UTC , which matches GMT + 0

Now let's try to parsear a date:

let fecha  = '2018-12-07 22:56:48'; //sin zona definida
let fecha2 = '2018-12-07 22:56:48+01:00'; //con mi zona
let fecha3 = '2018-12-07 22:56:48Z'; //con zona 00
let momento = moment(fecha);
let momento2 = moment(fecha2);
let momento3 = moment(fecha3);

//al no definir la zona se muestra siempre hora Zulu:

 
//asume mi zona del SO, le resta 1 hora
//En tu caso esta ejecución debería sumar 5 horas
console.log('sin formato', momento);

//especificamos que la zona es +1, le resta 1 hora para mostar la hora Zulú
console.log('sin formato', momento2);

//Explícitamente es Zulú, no tiene que sumar o restar
console.log('sin formato', momento3);

const formato='DD [de] MMM [del] YYYY [a las] hh:mm:ss A';

//Al usar un formato, se usa la hora local
console.log('con formato', momento.format(formato));
console.log('con formato', momento2.format(formato));
console.log('con formato', momento3.format(formato)); //Se le suma una hora a la Zulu

//formato, pero pidiendo utc:
console.log('con formato en UTC (+00)', momento.utc().format(formato));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>

So we see that the problem is that when you write:

let fecha_local = moment(fecha).utc().format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A');
console.log('Conversión: ', fecha_local);

You are making a conceptual error:

 moment(fecha) //parseas una hora local (-5)
  .utc() //pides que te la traslade a UTC (le suma 5 horas)
  .format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A'); // y la muestras
    
answered by 14.12.2018 / 18:21
source
6

The problem is that you are trying to pause a date that has no UTC information anywhere. That can be known immediately if we break down the date you use as input

let fecha = '2018-12-07 22:56:48'

The date would be 2018-12-07 and time 22:56:48 separated by space

The UTC information should go to the end as +hh:mm or -hh:mm , if it is in UTC it should be +00:00

  

If the time fragment is included, a UTC offset can also be included as + -HH: mm, + -HHmm, + -HH or Z

Changing the input date works perfectly. I used T as a separator.

moment.locale('es');

let fecha = '2018-12-07T22:56:48+00:00';

let fecha_origin = moment(fecha).local().format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A');
console.log('Fecha en local: ', fecha_origin);

let fecha_local = moment(fecha).utc().format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A');
console.log('En utc: ', fecha_local);
console.log('Offset', moment().utcOffset() / 60);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>

The other way is that instead of moment(fecha).utc() uses moment.utc(fecha) directly since as you say it comes in utc of the server.

moment.locale('es');

let fecha = '2018-12-07 22:56:48';

let fecha_origin = moment.utc(fecha).local().format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A');
console.log('Fecha en local: ', fecha_origin);

let fecha_local = moment.utc(fecha).format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A');
console.log('En utc: ', fecha_local);
console.log('Offset', moment().utcOffset() / 60);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>

The difference is as it is processed . Remember that your start date does not have offset information so if you use moment(fecha).utc() what it will do is interpret it as local time and then convert it to utc adding or subtracting hours (from there your problem). If you specify moment.utc(fecha) then will interpret as utc directly, that is +00:00

    
answered by 14.12.2018 в 18:12
1

utc () should go on the original date and on the local date apply local (). With the following example ami works perfectly for me. It should be like this the code:

moment.locale('es');

let fecha = '2018-12-07 22:56:48';

let fecha_origin = moment(fecha).utc().format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A');
console.log('Fecha original: ', fecha_origin);

let fecha_local = moment(fecha).format('DD [de] MMM [del] YYYY [a las] hh:mm:ss A');
console.log('Conversión: ', fecha_local);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>
    
answered by 14.12.2018 в 17:47
1

This way I get the date with the time zone you need: The image shows the capture in the console. (Take the test locally)

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>

<script>
	moment.locale('es');

	let fecha = '2018-12-07 22:56:48';

	let fecha_local = moment.utc(fecha).toDate();
	console.log('Conversión: ', fecha_local);
</script>
    
answered by 14.12.2018 в 22:52