Ejercicios con Date

Para manejar los datos de tiempo como (fecha y horas) Javascript utiliza el objeto  Date, que no es solo un string con un cierto formato. Es un objeto un poco particular que se basa en contar el número de milisegundos transcurridos desde la fecha de referencia 1/1/1970. Usando ese número es capaz de presentar la fecha del día en diferentes formatos y sabuendo ese detalle podremos hacer cálculos con fechas y tiempos. Antes de ponerte con los ejercicios repasa aquí el objeto Date  
Lo que se pide
Aclaraciones
En este ejercicio el usuario te dará su fecha de nacimiento y debes escribir la función que calcula el dia de la semana en que nació. Se supone que el usuario introducirá los datos numéricos correctamente y en una fecha real.
Por ejemplo si la fecha de nacimiento es el 3 de febrero de 1990 (3, 2, 1990) la función debe decirtes que nació en Sábado

function diaSemana(dia, mes, agno){

   let dias = new Array(7), fecha, diaSem;

   dias = ["Domingo","Lunes","Martes","Miércoles","Jueves", "Viernes","Sábado"];

   fecha = new Date(agno, mes, dia);

   diaSem = fecha.getDay();

   return dias[diaSem];

}

let dia = parseInt(prompt("Número del dia"));

let mes = parseInt(prompt("Número del mes"));

let agno = parseInt(prompt("Número del año"));

console.log("Naciste en "+diaSemana(dia, mes, agno));

Vamos a por el tradicional ejercicio donde el ordenador te va a saludar con un buenos días, buenas tardes o buenas noches según la hora del día. De 6 de la mañana 12 del medio día serán buenos días,  a partir de las 12 hasta las 20h serán buensa tardes y a partir de las 20h hasta las 6 de la madrugada serán buenas noches.

Por ejemplo entro en mi página a las 10am, la página me mostraría "Buenos días", pero si entro a las 14:30 me dirá Buenas tardes y si llego a las 11 de la noche a la 1 de la madrugada me dirá Buenas noches. 

function saludar(fecha){

let ahora, frase;

ahora = fecha.getHours();

switch (true){

    case ahora >= 6 && ahora < 12:

        frase = "Buenos días";

        break;

    case ahora >= 12 && ahora < 20:

        frase = "Buenos tardes";

        break;

    default:

        frase = "buenas noches";

}

return frase;

}

En este ejercicio debes crear una función que reciba como argumento un objeto fecha y devuelva un objeto con tres campos o propiedades: Un entero dia para el día del mes,
Un string Sem para el nombre día de la semana (castellano)
Un string mes: para el nombre del mes (castellano),
Un entero año: para el año con 4 dígitos

Los nombres de día y mes deben comenzar con mayúsculas.

Bueno una condición, intentad no utilizar arrays.

Es decir si llamo al script con la fecha correspondiente al 27/03/202 me debe devolver el objeto {dia: 23, sem: 'Lunes', mes:'Marzo', año: 2023}  

function objDate(fecha){

   let miFecha= {dia: null, sem:null, mes: null, año: null};

   miFecha.dia = fecha.getDate();

   //Uso la configuración regional para nombres

   miFecha.sem = fecha.toLocaleString("es-ES", {weekday: "long"});

   //Inicial a mayúscula

   miFecha.sem = miFecha.sem.replace(/^./, (v)=>v.toUpperCase());

   miFecha.mes = fecha.toLocaleString("es-ES", {month: "long"});

   miFecha.mes = miFecha.mes.replace(/^./, (v)=>v.toUpperCase());

   miFecha.año = fecha.getFullYear();

   return miFecha;

}

Crea una función diferencia que sea capaz de calcular el número de días transcurridos entre dos fechas dadas en la forma "año/mes/dia". El resultado debe ser un valor absoluto, o sea, el primer argumento será una fecha anterior o posterior al segundo, pero el resultado será un número de días, sin signo
Por ejemplo si pido diasEntre("2023/03/10", "2023/03/15") deberá devolver que el número entre esas fechas hay 5 días

function diasEntre(fecha1, fecha2){

   let f1 = new Date(fecha1);

   let f2 = new Date(fecha2);

   let msf1 = f1.getTime();   //milisegundos desde 1970 para fecha1

   let msf2 = f2.getTime();  //milisegundos desde 1970 para fecha2

   let dif = Math.abs(msf2 - msf1)/1000;  //diferencia en segundos

   let dias = Math.round(dif/86400);  //1 día son 86400 segundos

   return dias;

}

Este ejercicio va a consistir en crear un objeto similar al objeto Date, al que llamaremos MiDate, con los métodos: sumar, restar. Estos sumarán o restarán un número de días a la fecha representada por el objeto.
Por ejemplo creo el objeto miFecha (new MiDate() ) para tener el día de hoy. Si hago miFecha.sumar(1) tendré la fecha de mañana: hoy más 1 día.

//Extendemos el objeto Data a MiDate

class MiDate extends Date{

constructor(str=null){

   if(str===null){

      super()

   }

   else{

    super(str)

   }

}

sumar(dias){

   let ms = this.getTime() + dias*86400*1000;

   this.setTime(ms)

    }

restar(){

   let ms = this.getTime() - dias*86400*1000;

   this.setTime(ms)

   }

}

//Probamos a sumar 2 días al dia actual

miFecha = new MiDate();

miFecha.sumar(2);

console.log(miFecha.toLocaleDateString("es-ES", {dateStyle:'long'})

 

En este ejercicio vas a crear una función capaz de determinar el número de horas, minutos y segundos entre dos horas de un mismo día. La función que puedes llamar intervalo tiene dos argumentos string con los tiempos en formato hh:mm:ss

Si llamo a intervalo("12:20:30" , "14:25:00")  esto debería dar como resultado 2horas, 4minutos y 30 segundos.

function intervalo(t1, t2){

   let refer = "01/01/1970"; //dia de referencia de tiempos JS: 0h 0m 0s

   let dia = new Date(refer);

   let inst1 = new Date(refer+" "+t1);

   let inst2 = new Date(refer+" "+t2);

   let dif = Math.abs(inst1.getTime() - inst2.getTime());

   dia.setTime(dif)

   return dia.getHours()+"h "+dia.getMinutes()+"m "+dia.getSeconds()+"s";

}

console.log(intervalo("20:30:20", "22:40:00")); //2h:9m:40s

Escribe una función que determine cual de las dos horas que se le pasa como argumento es menor.

Se supone que ambos tiempos son horas de un mismo día y la solución se debe hacer usando el objeto Date.

Por ejemplo menorHora("12:20:00", "11:10:00") debiera de decir que la segunda hora es menor que la primera. 

function minTime(tiempo1, tiempo2){

   let refer = "1/1/1970";

   let t1 = new Date(refer+" "+tiempo1)

   let t2 = new Date(refer+" "+tiempo2)

   let menor;

   menor = t1.getTime() < t2.getTime()?t1:t2;

   return menor

}

console.log(minTime("12:10:00", "11:00:00"));

Esta función debe determinar si el año de una determinada fecha es bisiesto o no. Recuerda un año es bisiesto si es múltiplo de 4, excepto el primer año del siglo (1500, 1600...) que solo lo será es divisible por 400

Por ejemplo esBisiesto('1984/1/1') devolve´r que ('a', ['w','e','r','i']) devolverá que si lo es. Igualmente esBisiesto('1600/1/1') pero para esBisiesto('1800/1/1') dirá que no es bisiesto

function esBisiesto(fecha){

  let año 0 fecha.getFullYear()

  let bis = (año % 4 ==0) && (año%100 !=0 || año%400 == 0);

  return bis

}

let fecha = new Date("2000/10/20");

console.log(esBisiesto(fecha));    //dará true

fecha = new Date("1800/10/18");

console.log(esBisiesto(fecha));    //dará false

Te propongo que crees una función para determinar el número de días de cada mes, por supuesto sin usar arrays con meses y días, si no usando el objeto Date. La función recibe como argumento una fecha.

Así por ejemplo diasMes("2000/2/1"), es el mes de febrero de un año bisiesto, luego dará como resultado 29. diasMes("2023/1/1") dará 31.

function diasMes(fecha){

   let fechaAux, max = 31;

   let mesact = fecha.getMonth();

   fechaAux = new Date(fecha)

   fechaAux.setDate(max);

   if(fechaAux.getMonth() != mesact){

      max = 30;

      fechaAux = new Date(fecha);

      fechaAux.setDate(max);

      if(fechaAux.getMonth() != mesact){

         let año = fecha.getFullYear();

         let bisiesto = (año % 4 ==0) && (año%100 !=0 || año%400 == 0);

           max = bisiesto? 29:28;

      }

   }

return max;

}

En este ejercicio debes añadir un nuevo método al objeto Date, se llamara getWeek y debe devolver el número de semana para una fecha determinada.

Según la norma ISO 8601 las semana comienzan en Lunes y si  el año comienza antes del viernes esa es la semana 1 del año, en caso contrario esa es la última semana del año anterior. Si el año termina antes del jueves esa última semana se cuenta como semana 1 del año siguiente. 

Si defino el objeto fecha = new Date('2023/3/27') en tonces fecha.getWeek() me dará el número de la semana actual que es 13.
Para el 1 de enero de 2023 que fue domingo obtenemos que el num de semana es 52

function getWeek(){

 let añoAct, diaSemAct, mesAct, diaIni, msIni, msAct;

 let dias, diaSemini, semana;

 añoAct = this.getFullYear();

 diaIni = new Date(añoAct + '/1/1'); //primer día del año

 diaSemini = diaIni.getDay();

 diaSemini = diaSemini == 0 ? 7:diaSemini;

//Dia semana Domingo 7

 //La fecha está entre un viernes 1 y un domingo 3 de Enero

 // calculamos la última semana del año anterior

 diaSemAct = this.getDay();

  diaSemAct = diaSemAct == 0?7:diaSemAct;

  mesAct = this.getMonth()

 if( mesAct == 0 && (diaSemAct - this.getDate()) >3 ){

     let añoAnt = new Date((añoAct-1)+"/12/31");

     semana = añoAnt.getWeek();

  }

 else{

     //La fecha está entre un lunes y un miércoles de Diciembre

     //Calculamos la primera semana del año siguiente, que es 1

     if (mesAct == 11 && (this.getDate() - this.getDay() > 28)){

         semana = 1;

     }

    else{

         msIni = diaIni.getTime();

         msAct = this.getTime();

          //1 día son 86.400.000ms

         dias = Math.ceil((msAct - msIni)/(1000*86400));

         if(diaSemini <= 4){

                 dias = dias + diaSemini;

         }

         else{

             dias = dias - ( 7 - diaSemini);

         }

     semana = Math.ceil((dias)/ 7);

     }

 }

return semana;

}