Check time between two timeslots


#1

Hello people,
I am running a timetabling app using Meteor (offline) that takes in a CSV file as a string that contains Start Times and End Times. The format of the time is HH:MM PM/AM (E.g 11:45 AM / 12:00 PM) that’s start and end times.

I want the app to compare server time, and check if the current time (e.g 11:50 AM) and see if it is smaller than end time and greater than the start time, and show that relevant timeslot’s information.

I managed to make it show relevant information by checking if the current time equal to the start and end times of the timeslot, but that runs every second and makes the app very slow at times, and sometimes it activates two timeslots which cause the wrong slot to show with the right one. I’m sure there is a better way of doing it.

  Meteor.setInterval(() => {

    var nowTimes = Timetables.find({TimeEnd: whatTimeIsItString.get()});
    nowTimes.forEach((time) => {
      Timetables.update({_id : time._id },{$set:{isActive : false}});
    });

    var nowTimes = Timetables.find({TimeStart: whatTimeIsItString.get()});
    nowTimes.forEach((time) => {
      Timetables.update({_id : time._id },{$set:{isActive : true}});
    });
  }, 1000);

where WhatTimeIsItString.get() is a session that has the retrieved server time as a string.

Thank you for your help!


#2

I think you shoud subscriber time slots then process data on the client side. It’s better than calling methods or query every second on the server.


#3

I’m sorry, still a bit new to meteor. How can I do that?


#4

What if you don’t need to ask server? You can use moment to convert string to time on the client side.


#5

Yes I did that, by converting and parsing to int. I’m just struggling with how to approach the whole comparison bit. I would imagine something close to this pseudo

timetables.find({Timestart: greater than current time}, {TimeEnd: less than current time});

Am I on the right track? What would be the greater or equal / less or equal code in JS? I tried the ‘>=’ and ‘<=’ but they did not work.


#6

It’s mongodb, use $gt, $lt


#7

@izh93 It depends what you want to achieve exactly (why do you want to compare server time with the start-end interval), the amount of data to be processed, if the timetable changes or not (just one-time csv import and no change until next import?), what is the purpose of isActive field, etc …
It seems that this subscription would do the job

var currentServerTime = getServerTime();
timetables.find({ $and: [  
   { timeStart: { $gt: currentServerTime } },
   { timeEnd: { $lt: currentServerTime } } 
]});

I recommand to use moment package and normalize all time data you put in Collections with moment().toDate(), so all you queries in Mongo will be “native”.
Read this about camelCase, check you code with your editor with eslint


#8

Each slot has a start time and an end time. They are strings put in the CSV.
I want to show relevant time slots when the current time is between their start time and end time.
the isActive is just a way I hacked together very quickly to check if current time equal to start time (String comparison) and if so, set isActive to true, and hence showing the relevant information. It is set to false once the end time equals current time. It wintended inteded, but sometimes it activates the wrong slot and the wrong one stays active until its timeEnd is equal to current time (could be a whole day before that happens).

Hence, I wanted to figure out a way to compare current time and see if it is equal or in between start and end times, and return that particular collection document. I can’t seem to do so as the the CSV has the details in strings (eg 12:00 PM) , and I can’t seem to compare a string with a time (e.g timeStart(string): { $gt: currentServerTime(date) } I’m kind of stuck there.

How can I convert them to moment.js? I have dealt with momentjs before but still struggle with it.

I appreciate the time and effort you guys are investing in helping me.


#9

@izh93 when you do the insert from the csv file, store your timeStart/End in collection as Date type with this conversion

moment(timeReadFromCSV).toDate()

Tip : If your times in client/server/CSV are not in the same timezone, store and request everything as UTC

moment.utc(timeReadFromCSV).toDate()

#10

I solved the issue by originally placing the time as a number and in a 24-hour format (e.g 1800) in the CSV, and comparing in the client as follows:


  var timetable = Timetables.find({
    TS24: {
      $lte: Session.get("timeCheck")
    },
    TE24: {
      $gt: Session.get("timeCheck")
    }

where TS24 and TE24 are just the times in the 24 format, and Session.get("timeCheck") is just a session that gets the server time as a number in the same format (e.g 1315 is 1:15 PM).

I will test this over a 24-hour cycle and see if it produces any errors or doubling, otherwise, I will mark as solved. Thank you for your help, truly appreciated!