Estoy usando la biblioteca moment.js por tiempo.

Quiero verificar si la hora que obtengo del backend es entre las 8 a. m. y el mediodía (12 p. m.). Quiero almacenar todos los objetos cuya hora sea entre las 8 a. m. y las 12 p. m.

Obtengo la fecha en este formato: "2022-04-04T21:43:59Z". Quiero usar la zona horaria "America/Detroit".

Esto es lo que he intentado pero esto no funcionó;

  //this code is inside forEach loop
  moment.tz.setDefault($scope.userData.account.timeZone);
  var format = 'hh:mm:ss'
  var time = moment(response.date,format),
  beforeTime = moment('08:00:00', format),
  afterTime = moment('11:59:59', format);
  if (time.isBetween(beforeTime, afterTime)) {
     console.log('is between')
  } else {
     console.log('is not between')
  }

En la salida que obtengo is not betweenpara todos los datos, pero en realidad hay algunos datos que tienen fecha y hora entre las 8 a.m. y las 12 p.m. ¿Hay algo mal debido a la zona horaria?

respuesta

La razón por la que su comparación no funciona es porque no solo usa la hora sino también la fecha.

Primero debe extrapolar el tiempo de la fecha y hora de entrada y usar esos datos para hacer la comparación de esta manera:

let datetime = moment('2022-04-04T10:00:00Z', 'YYYY-MM-DDTHH:mm:ssZ');

moment({
  hour:datetime.hour(),
  minute:datetime.minute(),
  second:datetime.second()
}).isBetween(beforeTime, afterTime);
//returns bool true or false

Eso es porque esas 3 fechas y horas estarán en el mismo día solar y solo la hora será relevante para la comparación.

Además, trató incorrectamente los formatos al analizar las fechas y horas de entrada y las horas utilizadas antes y después.

Esta es una solución de trabajo que muestra el concepto:

//those are the formats your input uses for datetimes and times
const datetime_format = 'YYYY-MM-DDTHH:mm:ssZ';
const time_format = 'HH:mm:ss';

//this is your input crafted as objects having the prop date
var response_timeYESInBetween = {date : "2022-04-04T10:00:00Z"};
var response_timeNOTInBetween = {date : "2022-04-04T21:43:59Z"};

//moment.tz.setDefault($scope.userData.account.timeZone);

//this is where you parse those timestamp strings as moment datetime
var datetime_YESInBetween = moment(response_timeYESInBetween.date, datetime_format);
var datetime_NOTInBetween = moment(response_timeNOTInBetween.date, datetime_format);

//this is where those moment datetime get used to create new datetimes holding those same time but laying on today instead of their original dates
var timeonly_YESinBetween = moment({hour:datetime_YESInBetween.hour(), minute:datetime_YESInBetween.minute(), second:datetime_YESInBetween.second()});
var timeonly_NOTinBetween = moment({hour:datetime_NOTInBetween.hour(), minute:datetime_NOTInBetween.minute(), second:datetime_NOTInBetween.second()});

//this is where we create datetimes (ignoring to pass the date, sets them at today)
var beforeTime = moment('08:00:00', time_format);
var afterTime  = moment('11:59:59', time_format);

//we make the comparison to know which times are between beforeTime and afterTime
//note: now all those datetimes are all in the same day and only time will affect the comparison result
var firstComparison = timeonly_YESinBetween.isBetween(beforeTime, afterTime);
var secondComparison = timeonly_NOTinBetween.isBetween(beforeTime, afterTime)

console.log( firstComparison );
//outputs: true
console.log( secondComparison );
//outputs: false
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script>

Y si quisiéramos factorizar mejor las partes:

console.log( isBetween('2022-04-04T10:00:00Z', '08:00:00', '11:59:59') );
//true
console.log( isBetween('2022-04-04T21:43:59Z', '08:00:00', '11:59:59') );
//false

function isBetween(datetime, before, after){

    const datetime_format = 'YYYY-MM-DDTHH:mm:ssZ';
    const time_format = 'HH:mm:ss';

    let originalDatetime = moment(datetime, datetime_format);
    let transformed = moment({hour:originalDatetime.hour(), minute:originalDatetime.minute(), second:originalDatetime.second()});

    var beforeTime = moment(before, time_format);
    var afterTime  = moment(after, time_format);

    return transformed.isBetween(beforeTime, afterTime);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script>