Fechas en JavaScript

Trabajo con fechas y detalles importantes en JavaScript

  1. Conceptos basicos sobre el manejo del tiempo en informatica.
  • epoch – desde que fecha SO cuenta tiempo.
  • En Windows tiempo se mide en 10.000 ticks del procesador = 1 milisegundo.
  • .NET epoch 01.01.0001, SQL Server 01.01.1753, etc.
  • Ordenadores trabajan con numeros, no con fechas.
    2+2.1. La clase Date.
  • Diferencia entre fechas en milisegundos. Epoch 1/1/1970 a las 00:00:00 horas.
  • Al crear “new Date()” tendremos fecha actual.
  • .toLocaleDateString() convierte fecha en un string, aplicando formato de fecha local corta (ej: dd/MM/yyyy)
  • .toLocalTimeString() convierte en hora en un string, aplicando formato de hora local.
  • “new Date(0)” obtenemos fecha de referencia (epoch).
  • “new Date(1972,4,23)”. Creamos fecha 23 de mayo de 1972. IMPORTANTE, meses cuentan desde 0.
  • “new Date(72,4,22,21,0,0)”. Creamos fecha 22 de mayo de 1972 21:00:00. IMPORTANTE, meses cuentan desde 0, anyos de 2 caracteres representan 19XX.
  • Si en fecha ponemos valor mas que toca, lo suma a la fecha. “new Date(1972, 13, 10)” sera 10 de febrero del 1973, porque tiene exceso en el mes (+2). Podemos asi sumer dias, meses y anyos. Tambien podemos tener restar determinados elementos, ej: new Date(1972,2,-10) sera 20 de febrero 1972.
  • “new Date(“Feb 12, 2015 20:15:37 GMT+2″)” sera 12/02/2015 22:15:37.
  • Comprobar si es fecha: return (valor instanceof Date).
    2.2. TRUCO: Número de días de un mes cualquiera.
  • Pasar en parametro 0 en dia. Ej.: “new Date(anyo, mes+1, 0)”. Nos devolvera numero de ultimo dia del mes indicado. new Date(2012,2,0) sera 29 de febrero 2012. Acordar que 2 representa tercer mes del año.
    2.3. Las partes del tiempo.
  • getTime: obtiene solamente la parte correspondiente a la hora, rechazando la fecha. Devuelve el número de segundos transcurridos desde el 1/1/ 1970. Es útil para crear marcas de tiempo para ciertas aplicaciones especiales de comunicación con el servidor.
  • getDay: nos dice el día de la semana en el que nos encontramos, empezando a contar en domingo, que sería el día 0. De este modo el lunes sería el 1, el – martes el 2 y así sucesivamente.
  • getDate: obtiene el día del mes dentro de la fecha dada.
  • getMonth: devuelve el número correspondiente al mes contenido en el objeto Date. Se comienza a contar en 0, que correspondería al mes de Enero.
  • getYear: devuelve el año contenido en la variable de tipo fecha. Esta función tiene un comportamiento algo extraño puesto que devuelve 2 cifras para años – anteriores al 2000, y 3 cifras para años posteriores al 2000. Es decir, empieza a contar los años en el 1900. Así, para el año 1980 devolverá 80, para 2016 – devolverá 116 y para 1897 será el año -3 (negativo). Su uso no está recomendado y se prefiere la el método siguiente que es consistente en lo que devuelve.
  • getFullYear: funciona igual que el anterior, pero en este caso el año se devuelve siempre con las cuatro cifras correspondientes. Debemos usarlo – generalmente en sustitución de getYear, que se considera obsoleta.
  • getHours: permite obtener el valor de la hora en una variable Date, sin incluir la fecha actual, ni los minutos ni los segundos.
  • getMinutes: con este método conseguimos averiguar los minutos de la hora indicada.
  • getSeconds: permite obtener la parte correspondiente a los segundos en una variable de hora.
  • getMilliseconds: facilita el número de milisegundos después del segundo actual que está especificado dentro de una variable de tipo Date. Es decir, aunque la hora actual se muestre redondeada a 19:22:37, internamente hay unos cuantos milisegundos de precisión más que podemos obtener, por lo que sería por ejemplo 19:22:37:849 (siendo 849 los milisegundos a mayores que devolverá esta función).
    2.4. Formatos personalizados.
  • En formato español: return fecha.getDate() + “/” + fecha.getMonth() + “/” + fecha.getFullYear();
    2.5. Zonas y diferencias horarias.
  • Universal Coordinated Time, UTC o GMT (o Greenwich Meridian Time, hora en el meridiano de Greenwich). El UTC es mas preciso, pero se cree que UTC y GMT es lo mismo.
  • getUTCDay
  • getUTCDate
  • getUTCMonth
  • getUTCFullYear
  • getUTCHours
  • getUTCMinutes
  • getUTCSeconds
  • getUTCMilliseconds
  • Obtener la zona horaria actual: getTimezoneOffset. Indica horas de diferencia ente hora local y hora UTC. Diferencia horaria no son horas completas.
    2.6. Métodos de modificación de fechas:
  • setDate: Permite asignar un nuevo día del mes a la fecha contenida en una variable.
  • setMonth: Asigna un nuevo valor para el mes en la fecha contenida en la variable. Recuerda que los meses empiezan a contar desde 0 para enero.
  • setYear: Permite cambiar el valor del año en una fecha. Si se usan sólo dos dígitos como argumento se considerará un año dentro del rango 1900-2000.
  • setFullYear: idéntico al método anterior pero se deben especificar siempre los cuatro dígitos del año. Es más recomendable que la anterior. Este método permite especificar opcionalmente el mes y el día del mes como segundo y tercer parámetro respectivamente.
  • setTime: permite asignar una nueva hora pasando como argumento el número de milisegundos transcurridos desde la medianoche del 1/1/1970. No se utiliza demasiado por razones obvias.
  • setMilliSeconds: fija el número de milisegundos que pasan del segundo en la hora actual de una variable.
  • setSeconds: permite fijar el número de segundos actuales en la variable. Opcionalmente se pueden especificar también los milisegundos como segundo parámetro.
  • setMinutes: fija los minutos actuales en la hora contenida en una variable. Tiene como parámetros opcionales el número de segundos y el de milisegundos transcurridos.
  • setHours: nos permite fijar la hora actual para una variable tipo Date. Tiene como tres parámetros opcionales los minutos, segundos y milisegundos.
    O en UTC:
  • setUTCDate
  • setUTCMonth
  • setUTCFullYear
  • setUTCMilliSeconds
  • setUTCSeconds
  • setUTCMinutes
  • setUTCHours
    2.7. Operaciones con fechas
  • Comparaciones basicas: date1>date2, date2>=date1, date1==date2 (compara objetos, normalmente devuelve false, mejor usar ===).
  • Uso de “+” para fechas suma fechas en formato string.
  • Uso de “*” no aporta nada.
  • Uso de “-” da diferencias en milisegundos, muy util y funciona bien.
  • Saber diferencia en dias: difDias = diferenciaEnMilisegundos / (24 * 60 * 60 * 1000).
  • Saber diferencia en meses: difDias = diferenciaEnMilisegundos / (30 * 24 * 60 * 60 * 1000).
  • Obtener numero de milisegundos: Date.parse(fechaBase).
  • Sumar 5 dias a fecha: base.setDate(base.getDate() + 5). Luego para representar en fecha: new Date(base.setDate(base.getDate() + 5)).
  • Sumar 13 segundos a fecha: base.setSeconds(base.getSeconds() + 13). Luego para representar en fecha: new Date(base.setSeconds(base.getSeconds() + 13)).
  1. Temporizadores y cronómetros
  • Para ejecutar codigo a intervalos regulares de tiempo.
  • Los timeouts ejecutan codigo 1 vez.
  • Los interval ejecutan codigo varias veces cada X.
    Formato: tempID = setTimeout(“Rutina”, Tiempo); “Rutina” – (opcion 1) nombre de un procedimiento o función a ejecutar, Tiempo – valor en milésimas de segundo. (opcion 2) Rutina tambien puede ser cadena a ejecutar “alert(‘Hola’)” (se considera como mala practica). (opcion 3) Función anonima con codigo a ejecutar.
  • setTimeout: anota valor de tiempo y devuelve referencia al temporizador. Ej: var miId = setTimeout(“miFuncion()”, 2000);
  • clearTimeout: para cancelar antes de que se ejecuta. Ej: clearTimeout(miId);
  • setInterval: definir cada cuanto ejecutar una función. Ej: id = setInterval(“Mifuncion()”, 2000);
  • clearInterval: parar un interval para que no se ejecuta mas. Ej: clearInterval(id);
    A los “set..” podemos pasar todos parametros que queremos: setTimeout(Mifuncion, 2000, parametro1, parametro2…);
    Estos metodos no son de JavaScript, sino del navegador. En NodeJS los volvieron a implementar.
    3.1. La precisión de los intervalos de tiempo.
    Intentar evitar valores muy pequeños. Mejor por encima de 100 milisegundos.
    JavaScript solamente posee un hilo de ejecución (excluyendo web workers de HTML).
    setTimeOut y setInterval ejecutan en mismo hilo.
    Si proceso dura mas que tiempo entre intervalos se iran metiendo en cola para ejecutarse. Y en cola puede haber solo una tarea de cada tipo, resto se descartan.
    Para asegurar que se ejecuta funcion despues de haberse ejecutado: function periodica() { setTimeOut(periodica, 100); }
    var divreloj = null; // variable global. En un timer buscaremos este div solo una vez, para luego aprovecharse de que ya lo tenemos y no tenemos que volver lo a buscar.

Matrices en JavaScript

Importantes detalles sobre matrices en JavaScript

  1. Definición y uso básico de matrices (se numeran desde 0). Ej.: var arr = new Array() o “new Array(3)” o “[]” (si ponemos [3] es matriz con 1 elemento con valor 3); arr[0] = “coche”;
    arr.length – longitud de matriz. No solo leemos este valor, podemos escribir lo para redimencionar y nuevos elementos estaran sin definir. Cuidado no eliminar asi elementos.
    Semi foreach en JS:
    for(var coche in coches){
    alert(coches(coche));
    }
  2. Inicialización de matrices y matrices multidimensionales.
    var coches = new Array(“1″,”2″,”AD”); var coches = [“1″,”2″,”AD”]; var distintos = [“cadena”, 5, true];
    Multidimencionales: var dim1 = [1,2,3,4,5]; var dim2 = [1,2,3,4,5]; var dim2D = [dim1,dim2]; alert(dim2D[0][0]);
    Matrices escalonadas son las que contienen dentro matrices de diferentes dimenciones.
  3. Generar un alfabeto.
    Parseamos a numero: parseInt(“algo”);
    Comprobar si no es numero: if(isNaN(variable));
    Pide inputbox al usuario: prompt(“Pon numero”, “Valor defecto 26”);
    Cuando mostramos por pantalla matrices como string, separa valores con comas.
  4. Matrices asociativas: no los implemente realmente este tipo de matrices. Realmente es definicion de propiedades
    coches[“Alemanes”] = [“Audi”, “Volkswagen”, “Porsche”];
    alert(coches[“Alemanes”]) o por acceso a propiedad alert(coches.Alemanes);
  5. Manipulación de elementos de matrices.
    Unir en string usando elemento: var mEjemplo = [0,1,2,3,4,5]; mEjemplo.join(“–“); // Por defecto comas.
    Unir matrices: var mat1 = [1,2,3]; var mat2 = [“A”,”B”,”C”,”D”]; var nuevaMatriz = mat1.concat(mat2);
    Subconjunto de matrices (extracción): var subConjunto = sourceMatriz.slice(2,5); // Elementos del 2 al 5
    Matrices se pasan por referencia porque son objetos.
    Quitar elementos de matriz: matriz.splice(3,2) // Retira desde elemento 3, 2 elementos. Y resto de elementos se mueven para que no quedan huecos.
    Colas: var matriz = [1,2,3,4]; matriz.unshift(5,6) – meter al principio de cola; matriz.shift() – quita primer elemento.
    Pilas: var matriz = [1,2,3,4]; matriz.push(5) – meter en matriz; matriz.pop() – quita de matriz.
    Ordenacion:
    mat.reverse() (hace vuelta a elementos de matriz cambiando orden original de matriz);
    mat.slice().reverse() (copia matriz y invierte copia);
    mat.sort() (ordena la matriz como si fueran cadenas basando en valores unicode);
    Ordenacion especifica: var frutas = [“Naranjas”, “Pera”, “Melocoton”]; function ord(f1,f2){ return 0/1/2; frutas.sort(ord);
    Busquedas:
    mat.indexOf(“cadena buscada”) -> devuelve posición de primera ocurrencia de la cadena en la matriz.
    mat.indexOf(“cadena buscada”, 4) -> devuelve posición de primera ocurrencia de la cadena en la matriz despues de posición 4.
    lastIndexOf(“cadena buscada”) -> devuelve posición de ultima ocurrencia de la cadena en la matriz.
    Si se devuelve -1 -> no lo encuentra.
    Shims – funciones que sustituyen funciones si las primeras no existen.
    Procesamiento de elementos:
    Filtrar y extraer los que cumplen determinada condicion: var pares=mat.filter(esPar); function esPar(n){return n%2==0;}
    Indica si alguno cumple: mat.some(esPar);
    Indica si todos cumplen: mat.every(esPar);
    Aplica funcion a todos elementos en su retorno sin modificar matriz original: mat.map(elDoble); function elDoble(n){return n*2;}
    Map / Reduce para muchos datos.
    Aplicar funcion sin modificaciones: mat.forEach(mostrar); mostrar(n, indice, referenciaMatriz){alert(“Indice:”+indice+”,valor:”+n);

Detalles sobre JavaScript

Diferentes pequeños detalles de JavaScript que no se utilizan de forma muy habitual, pero que son bastante útiles.

  1. ScratchPatch (Firefox Shift+F4) – para escribir JS y ejecutar. Usa console.log(…) con consola (F12). Para poder hacer copy/paste escribir “permitir pegar” o “allow pasting” y CTRL+R.
    2.1. Operador ternario. Ej.: (n%2) == 0 ? alert(“numero par”) : alert(“numero impar”);
    2.2. Cortocircuito de expresiones lógicas. && o ||. Si primeras condiciones no se cumplen, resto no se verifican.
    2.3. Valores pseudo-Booleanos: Truly y Falsy (falsosos y verdosos). Ej.: if (window.Worker).
    Importante el orden: alert(“cualquier cosa” && true) -> true, alert( true && “cualquier cosa”); -> “cualquier cosa”. Operadores && y || devuelven valor de primer o segundo operando, no solo true/false. En && si primero es false, se devuelve primero, en || si primero es true se devuelve primer operando. Convertir algo en un booleano siempre con !!: !!”variable”. Se utiliza mucho en “return !!res;” en funciones.
  2. Uso avanzado de bucles determinados. Cambiar y complicar partes de los bucles. for (; i< 10; i++), for (var i = 0, j = 10; i< j; i++), for (var i = 0; ; i++), for (var i = 0, j = 0; i<10 && j < 5; i++, j++), for (;;)
  3. Uso de expresiones complejas con switch. Truco para tener condiciones complejas:
    switch (true) {
    case x > 0 && x < 10: alert(“x > 0 && x < 10”); break; case x > 0 && x < 20: alert(“x > 0 && x < 20”); break; case x < 0 || x > 100:
    alert(“x < 0 || x > 10”);
    break;
    default:
    alert(“Ninguno”);
    }
    5.1. Ámbito de las variables. Global desde cualquier parte de codigo (se define fuera de función). Local – solo dentro de una función.
    5.2. Shadowing u ocultamiento de variables. Cuando funcion tiene variable con mismo nombre en distinto ambito, prevalece la de ambito menor.
    5.3. Hoisting o elevación. Hay diferencia entre variable no definida y la que no existe. Si se define mas tarde, javascript lo mueve por dentro al principio de la función.
    5.4. Sobrecarga de funciones. Podemos tener mas argumentos de los definidos. Ej.:
    funcion sumarNumeros(){
    var parcial = 0;
    for (var i=0;i, <, etc.). Comparación teniendo en cuenta lenguaje indicado con “localeCompare”. Por defecto usa lenguaje de navegador.

Como crear métodos adicionales a clases existentes en C# como en JavaScript

Teniendo clases ya existentes sin heredar de ellos, les podemos añadir nuevos métodos (extensoras) en JavaScript gracias a los prototipos, pero en C# también es posible.

Para conseguir esto en C#:

En un fichero aparte, por ejemplo en carpeta Extensions creamos clase con siguiente código:

public static class StringExtensions
{
public static String trim(this String s)
{
return s.Trim();
}
}
Para utilizar:
String s = " Test ";
s = s.trim();

Parece un método propio, pero realmente es lo mismo que llamar a un método estático:
String s = " Test ";
s = StringExtensions.trim(s);

Formato JSON en respuestas SQL Server >= 2016

Se puede forzar a una base de datos normal, que devuelve datos en formato JSON. Para ello se necesita realizar modificaciones en la consulta.

Basicamente es instrucción “FOR JSON“, gracias a la cual SQL Server devuelve datos y les da formato JSON a los resultados de consulta.

Por ejemplo:

SELECT campo1, campo2 FROM tabla1 FOR JSON AUTO;

SELECT TOP (10) [TagId]
      ,[ValueBool]
      ,[ValueInt]
      ,[ValueFloat]
      ,[ValueStr]
      ,[ValueEnumId]
      ,[SourceTimestamp]
      ,[UpdateTimestamp]
      ,[QualityId]
      ,[QualityDetailId]
      ,[QualitySourceId]
  FROM [DBEjemplo].[System].[TagValues]
  FOR JSON AUTO, INCLUDE_NULL_VALUES