The DateTime Dilemma: Solving UTC Storage and Local Filtering Discrepancies in MongoDB , React.

Introduction

As a developer, you often encounter unexpected challenges that make you scratch your head. Today, I want to share a recent conundrum I faced at work involving MongoDB, React, and the ever-tricky world of date time zones.

Problem Statement

Imagine this : As a Full Stack Developer , you are working on where users can filter data based on dates. Sounds simple, right? Well, not so fast. While applying the filters , I found some the things, which were hindering the feature:

  1. MongoDB, was diligently storing all datetime values in UTC format. Good practice, MongoDB!

  2. On frontend, we were using react-date-range package to send the date filter to Node-Express backend.

  3. Basically our React frontend, was operating in the user's local time zone.

  4. When we sent the selected dates to our backend for querying, we weren't accounting for the time zone difference.

The result? A mismatch between what the user intended to filter and what our database was actually querying.

How to solve this issue?

To resolve this issue, we implemented the following steps:

  • Installed moment package on both frontend and backend repository.

  • While sending the date from Frontend, send it in the format of Date ("YYYY-MM-DD").


import moment from "moment";
import {useCallback} from "react";
//React Component
const Home = () => {

    const searchDate = useCallback(
        let startDate = moment(<date>).format("YYYY-MM-DD");
        let endDate = moment(<date>).format("YYYY-MM-DD");
        //Backend call
        getAllRoutes({startDate,endDate}).then((data)=>setData(data))
    ,[]);


    return (
    // <Component/>
    );
};
  • On the backend Express, here's how we implemented:
 async function getAllRoutes(req,res) {

    let query = {};
    //Other logic

    const startDateObject = moment(startDate)
        .startOf("day")
        .utcOffset("+05:30", true)
        .toDate();

//* This sets the UTC offset to +05:30, which is the time zone for India 
// (IST - Indian Standard Time).
//* The true parameter keeps the local time the same and 
// shifts the underlying UTC time.
//* This is crucial for ensuring that the date is interpreted in Indian time, 
//regardless of the server's time zone.

      const endDateObject = moment(endDate)
        .endOf("day")
        .utcOffset("+05:30", true)
        .toDate();

      query.$and = query.$and || [];

      query.$and.push(
        { departure_time: { $gte: startDateObject } },
        { arrival_time: { $lte: endDateObject } }
      );
      try {
        const routes = await TrainRoutes.find(query);
        res.status(200).json({
            success: true,
            routes,
        });
       }catch(error){
           res.status(500).json(
       }

    }

Why Moment.js ?

Moment.js proved to be a game-changer for several reasons:

  1. Simplicity: It provides an intuitive API for handling date conversions and formatting.

  2. Time Zone Support: Moment.js has robust support for working with different time zones.

  3. UTC Conversion: The library makes it trivial to convert local times to UTC and vice versa.

  4. Compatibility: It works seamlessly with both our React frontend and Node.js backend.

What we learned?

  • Always be mindful of time zones when working with dates, especially in distributed systems.

  • When using MongoDB (or any database that stores in UTC), ensure your application logic accounts for time zone conversions.

  • Leverage robust libraries like Moment.js to handle complex date and time operations.

  • Test your date-related features across different time zones to catch potential issues early.

Also remember, whether you're using MongoDB, React, or any other technologies, always pay close attention to how you're handling dates and times. It might just save you from a major headache down the road!

Thank you for reading, below are the references that I read ...!!!

References