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