🌙 The Midnight Panic: “Why Is Tomorrow Showing Up Today?!”
It was 2 AM in Bangalore. Our Slack channels were lighting up.
Out Client, the Malaysia team, busy entering driver incentives, suddenly noticed a strange issue: the CMS showed a booking as completed on 03 Jan 2025, but the driver mobile app said it was 04 Jan 2025.
Users were confused, and our mobile developer was off hiking in the Himalayas. Things were heating up!
The problem was simple: our booking data had a timestamp like 2025-01-03T21:13:28.038Z
(which is in UTC). However, the mobile app was using Moment.js to display the date like this:
moment(i?.completed_booking_date || "").format("DD MMM YYYY")
This code converted the UTC time into the device’s local time. In Malaysia (UTC+8), that extra 8 hours pushed the date from 03 Jan to 04 Jan. Our backend and drivers both confirmed the correct date, but the mobile app was off by one day.
👻 The Issue: Moment.js and Timezone Trouble
The mobile code above did exactly what it was told: it took the UTC timestamp and converted it to local time. For example:
UTC: 03 Jan 2025 @ 21:13
+8 hours = 04 Jan 2025 @ 05:13 → "04 Jan 2025"
That extra conversion caused the mobile app to show the wrong date for users in Malaysia.
💡 The “Aha!” Moment: Two Simple Steps to Fix It
Since we couldn’t change the mobile code right away, we came up with a temporary fix on the backend. We decided to “lie” to the mobile app by giving it a date that could not be misinterpreted. Here’s what we did:
Step 1:
Hijack the completed_booking_date
field and replace the raw ISO string with a pre-formatted UTC date string.
We looped through our booking data and changed the date from 2025-01-03T21:13:28.038Z
to a plain string: "03 Jan 2025".
// Backend code magic ✨
bookings = bookings.map((booking) => ({
...booking,
completed_booking_date: moment
.utc(booking.completed_booking_date) // Lock it to UTC!
.format("DD MMM YYYY"), // Output: "03 Jan 2025"
}));
Step 2:
Force-feed the mobile app a date it couldn’t misinterpret.
Now the mobile app receives a simple string—there’s no time data left, so Moment.js has nothing to convert. Our simulation showed that every user now sees "03 Jan 2025".
// Simulated mobile app formatting logic
bookings.forEach((booking) => {
const mobileDisplay = moment(
booking.completed_booking_date,
"DD MMM YYYY"
).format("DD MMM YYYY");
console.log("Mobile App Output (After UTC Conversion):", mobileDisplay);
});
🕵️ Testing with Docker: Our Virtual Time Machine
To be sure our fix worked around the world, we used Docker to simulate different timezones. By setting the TZ
environment variable, we could test our code as if we were in New York, Kolkata, or Kuala Lumpur. Here’s our simple shell script:
#!/bin/bash
set -e
# Create a .dockerignore file if it doesn't exist, to exclude node_modules
if [ ! -f .dockerignore ]; then
echo "node_modules" > .dockerignore
echo "Created .dockerignore to exclude node_modules."
fi
# Build the Docker image
echo "Building Docker image..."
docker build -t my-node-app .
# Define the timezones to test
timezones=("America/New_York" "Asia/Kolkata" "Asia/Kuala_Lumpur")
# Loop through each timezone and run the container
for tz in "${timezones[@]}"; do
echo "========================================"
echo "Running for timezone: $tz"
echo "========================================"
docker run -e TZ="$tz" my-node-app
echo ""
done
echo "All tests completed."
Test Results:
Timezone | Before Fix | After Fix |
---|---|---|
New York | 03 Jan ✅ | 03 Jan ✅ |
Kolkata | 04 Jan ❌ | 03 Jan ✅ |
Kuala Lumpur | 04 Jan ❌ | 03 Jan ✅ |
Our tests confirmed that our fix worked everywhere. By giving the mobile app a plain date string, we stopped it from applying any unwanted timezone conversion.
🎉 How We Saved the Day with a Quick Backend Hack
Without needing a mobile update or waiting for app store approvals, we solved the problem with two simple steps:
- Hijack the date field: Replace the ISO string with a pre-formatted UTC date string.
- Force-feed the mobile app: Give it a date that cannot be misinterpreted.
This quick fix turned 2025-01-03T21:13:28.038Z
into "03 Jan 2025", and our users—no matter where they were—saw the correct date.
🚨 Epilogue: A Temporary Fix That Made a Big Difference
Eventually, the mobile team updated the app to use moment.utc()
, but our backend fix remained in place because it worked so well. Sometimes, a simple temporary solution is the best solution when you’re under pressure.
For more details and to try it yourself, check out our repo:
Moral of the story: Timezones can be a real pain. When things get tough, hack smart and keep it simple!
Top comments (0)