基于起始与结束时间戳计算已完成时间占比(React场景)
Let’s walk through how to compute the time completion percentage and tie it to your React progress bar—since you already have the countdown working, this should fit right in!
Step 1: Parse API Time Strings into Date Objects
First, convert the start_time and end_time strings from your API into JavaScript Date instances. This lets us do proper time calculations:
// Convert API strings to Date objects const startTime = new Date(start_time); const endTime = new Date(end_time);
Quick note: If you run into parsing issues with the "YYYY-MM-DD HH:mm:ss" format, tweak the string to ISO standard by replacing the space with T:
const startTime = new Date(start_time.replace(' ', 'T'));
Step 2: Calculate Completion Percentage
We need to compute three things: total event duration, elapsed time since the start, and then clamp the percentage between 0 and 100 to avoid edge cases (like before the start time or after the end time):
const getCompletionPercentage = (start, end) => { const now = new Date(); const totalDuration = end.getTime() - start.getTime(); // Handle cases where start/end are the same or invalid if (totalDuration <= 0) return 100; const elapsedTime = now.getTime() - start.getTime(); // Ensure percentage stays between 0-100 return Math.max(0, Math.min(100, (elapsedTime / totalDuration) * 100)); };
Step 3: Integrate into Your React Component
Since time is dynamic, use useState to track the percentage and useEffect to update it periodically (every second works well for a progress bar). Here’s a complete component example:
import { useState, useEffect } from 'react'; const TimeProgressBar = ({ start_time, end_time }) => { const [completionPercent, setCompletionPercent] = useState(0); useEffect(() => { const startTime = new Date(start_time); const endTime = new Date(end_time); // Update percentage function const updateProgress = () => { const percent = getCompletionPercentage(startTime, endTime); setCompletionPercent(percent); // Stop updating once we hit 100% if (percent >= 100) clearInterval(intervalId); }; // Initial calculation updateProgress(); // Refresh every second const intervalId = setInterval(updateProgress, 1000); // Cleanup interval when component unmounts or props change return () => clearInterval(intervalId); }, [start_time, end_time]); // Reuse the percentage calculation function const getCompletionPercentage = (start, end) => { const now = new Date(); const totalDuration = end.getTime() - start.getTime(); if (totalDuration <= 0) return 100; const elapsedTime = now.getTime() - start.getTime(); return Math.max(0, Math.min(100, (elapsedTime / totalDuration) * 100)); }; return ( <div style={{ width: '100%', height: '24px', background: '#eee', borderRadius: '12px' }}> <div style={{ width: `${completionPercent}%`, height: '100%', background: '#4CAF50', borderRadius: '12px', transition: 'width 0.3s ease', // Smooth width animation }} /> {/* Optional: Show percentage text */} <p style={{ textAlign: 'center', marginTop: '8px', margin: 0 }}> {Math.round(completionPercent)}% Complete </p> </div> ); }; export default TimeProgressBar;
Key Edge Cases to Consider
- Invalid Dates: Add a check to ensure
startTimeandendTimeare valid (e.g.,if (isNaN(startTime.getTime())) return 0;). - Time Zones: If your API times are in UTC, append
Zto the string when parsing (e.g.,new Date(start_time + 'Z')) to avoid local time zone mismatches. - Performance: Updating every second is efficient, but if you want smoother animations, you can reduce the interval to 500ms—just be mindful of unnecessary re-renders.
内容的提问来源于stack exchange,提问作者cosmichero2025

