Calculate time remaining before a booking ends with Momentjs in React Native

Viewed 699

I have an array of data I'm mapping through where a user selects certain time slots to book meeting rooms and am trying to take the end_date of this booking and work out how many hours/minutes are remaining before this booking ends.

I am trying to do this using Momentjs and wondering what the best way to do so would be.

My array of data consists of a few different bookings so I'm mapping through and rendering the 'Time Left' in different cards in the UI.

My array looks like this:

[
   {
     created_at: "2021-08-19T13:20:26.000000Z"
     end_date: "2021-08-19 17:59:50"
     id: 171
     key_id: "30654908"
   }
]

And my code currently looks like this:

const ActiveSession = ({navigation}) => {
  const {bookings} = React.useContext(StateContext);

  console.log(bookings);

  let now = moment()
  console.log(now);

return (
    <>
      {bookings.map((booking, index) => (
        <View style={styles.subContainer} key={index}>
          <View style={styles.topbar}>
            <Image
              style={styles.tinyLogo}
              source={{uri: booking.pod.location.image}}
            />
            <View>
              <Text>
                <Text style={{fontWeight: 'bold'}}>{booking.pod.name}</Text>
              </Text>
              <Text>{`Time left - ${moment(booking.end_date).format('H:mm')}</Text>
            </View>
          </View>
       </>
     )
   }

As you can see, I have the end_date in the correct time format but am unsure of how to subtract the current time from it, especially if its over an hour.

It could be just a few minutes before the booking ends or several hours etc. I know this is probably an easy one but any help would be very much appreciated!

Thanks in advance.

1 Answers

I had to assume some data and used useState to be able to rerender the screen every second but here is a working example. Let me know if this is what you were looking for.

import React, { useEffect, useState } from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
import moment from 'moment';

const formatTime = (duration) => {
  var hours = Math.floor(duration / 3600);
  var minutes = Math.floor((duration % 3600) / 60);
  var seconds = duration % 60;

  if (hours < 10) {
    hours = '0' + hours;
  }
  if (minutes < 10) {
    minutes = '0' + minutes;
  }
  if (seconds < 10) {
    seconds = '0' + seconds;
  }
  return hours + ':' + minutes + ':' + seconds;
};

const ActiveSession = ({ navigation }) => {
  // const { bookings } = React.useContext(StateContext);
  const [bookings, setBookings] = useState([
    {
      created_at: '2021-08-19T13:20:26.000000Z',
      end_date: '2021-08-19 17:59:50',
      id: 171,
      key_id: '30654908',
      timeLeft: moment('2021-08-19 17:59:50').diff(moment(), 'seconds'),
    },
    {
      created_at: '2021-08-19T15:20:26.000000Z',
      end_date: '2021-08-19 18:59:50',
      id: 172,
      key_id: '30654908',
      timeLeft: moment('2021-08-19 18:59:50').diff(moment(), 'seconds'),
    },
    {
      created_at: '2021-08-19T16:20:26.000000Z',
      end_date: '2021-08-19 19:59:50',
      id: 173,
      key_id: '30654908',
      timeLeft: moment('2021-08-19 19:59:50').diff(moment(), 'seconds'),
    },
  ]);

  useEffect(() => {
    const timer = setInterval(() => {
      const newBookings = bookings.map((booking) => {
        return {
          ...booking,
          timeLeft: moment(booking.end_date).diff(moment(), 'seconds'),
        };
      });
      setBookings(newBookings);
    }, 1000);
    return () => {
      clearInterval(timer);
    };
  }, [bookings]);

  return (
    <>
      {bookings.map((booking, index) => (
        <View style={styles.subContainer} key={index}>
          <View style={styles.topbar}>
            {/* <Image
              style={styles.tinyLogo}
              source={{ uri: booking.pod.location.image }}
            /> */}
            <View>
              <Text>
                {/* <Text style={{fontWeight: 'bold'}}>{booking.pod.name}</Text> */}
                <Text style={{ fontWeight: 'bold' }}>{booking.id}</Text>
              </Text>
              <Text>{`Time left - ${moment(booking.end_date).format(
                'H:mm'
              )} ${formatTime(booking.timeLeft)}`}</Text>
            </View>
          </View>
        </View>
      ))}
    </>
  );
};

const styles = StyleSheet.create({});

export default ActiveSession;
Related