CalHeatmap异步加载数据时调整时间戳至Europe/Berlin时区失败求助
Fixing Timezone Conversion Issues with CalHeatmap and Moment-Timezone
Let's break down why your current code isn't working and how to fix it to properly map your timestamps to the Europe/Berlin timezone for CalHeatmap.
Why Your Original Code Fails
The main issues with your existing code are:
- You're using a Moment.js object directly as an object key. When you do this, JavaScript automatically converts the object to a human-readable string (like
Wed Sep 11 2024 12:00:00 GMT+0200 (Central European Summer Time)), which isn't the numeric timestamp format CalHeatmap expects to group calendar days. - You aren't aligning timestamps to the start of the day in the target timezone. CalHeatmap organizes data by calendar dates, so you need to map each raw timestamp to the exact start of its corresponding day in Europe/Berlin.
Step-by-Step Solution
First, make sure you have moment-timezone installed and imported correctly (either via npm or CDN). Then modify your afterLoadData function to handle timestamp conversion properly:
afterLoadData: function(timestamps) { const results = {}; // Iterate over each timestamp-value pair from your server for (const [timestampKey, value] of Object.entries(timestamps)) { // Convert the timestamp string to a number (assumes milliseconds; multiply by 1000 if using seconds) const originalTimestamp = parseInt(timestampKey, 10); // 1. Parse the UTC timestamp into a Moment object locked to Europe/Berlin timezone const berlinDateTime = moment.tz(originalTimestamp, 'Europe/Berlin'); // 2. Adjust the time to the start of the day in Berlin (00:00:00) const berlinDayStart = berlinDateTime.startOf('day'); // 3. Convert back to a UTC millisecond timestamp to use as the new key const adjustedTimestamp = berlinDayStart.valueOf(); // Aggregate values if multiple timestamps fall on the same Berlin day if (results[adjustedTimestamp]) { results[adjustedTimestamp] += value; } else { results[adjustedTimestamp] = value; } } return results; }
Key Details to Note
- Timestamp Unit: If your server returns second-level timestamps instead of milliseconds, multiply the parsed value by 1000 (e.g.,
const originalTimestamp = parseInt(timestampKey, 10) * 1000;). - ISO String Input: If your server returns ISO 8601 strings (like
"2024-09-11T00:00:00Z") instead of numeric timestamps, pass the string directly tomoment.tz:const berlinDateTime = moment.tz(timestampKey, 'Europe/Berlin'); - Custom Aggregation: The code sums values for timestamps that fall on the same Berlin day. Adjust this logic (e.g., increment a count instead of summing) if your use case requires it.
Verify the Fix
After updating the code, log the results object to confirm the keys are numeric timestamps corresponding to the start of each day in the Europe/Berlin timezone. CalHeatmap should now display data aligned to Berlin's calendar days instead of your browser's local timezone.
内容的提问来源于stack exchange,提问作者fefe
相关产品推荐
相关产品推荐

