Keywords: JavaScript | ISO-8601 | Week_Calculation | UTC_Time | Date_Processing
Abstract: This article provides a comprehensive exploration of implementing ISO-8601 week number calculations in JavaScript, covering core algorithms, UTC time handling, prototype method extensions, and cross-browser compatibility testing. By comparing with PHP's date('W') functionality, it offers complete code implementations and performance optimization recommendations for accurate international date handling.
Overview of ISO-8601 Week Number Standard
The ISO-8601 international standard defines week-based date representations where each week starts on Monday, and the first week is the one that contains the first Thursday of the year. This representation is particularly important for international applications and cross-timezone systems, ensuring consistency in date calculations.
Core Algorithm Implementation
The core algorithm for obtaining ISO week numbers is based on the principle of finding the nearest Thursday. Since the ISO standard specifies that the first week must contain the first Thursday of the year, adjusting the date to the nearest Thursday accurately determines the week number and year to which the date belongs.
Basic function implementation:
function getWeekNumber(d) {
// Create UTC date copy to avoid modifying original date
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
// Adjust to nearest Thursday
// Convert Sunday from 0 to 7, maintaining Monday as 1 consistency
var dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
// Calculate UTC time for first day of the year
var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
// Calculate complete weeks
var weekNo = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
return [d.getUTCFullYear(), weekNo];
}
Importance of UTC Time Handling
Using UTC methods for date processing is crucial, especially during daylight saving time transitions. JavaScript's local date methods are affected by user timezone settings, which can lead to incorrect week number calculations. By consistently using UTC, uniform week number results can be ensured across any timezone worldwide.
Advantages of UTC processing include:
- Avoiding date offsets caused by daylight saving time transitions
- Ensuring consistency in cross-timezone applications
- Eliminating the impact of local timezone settings on calculations
Prototype Method Extension
For convenient daily use, the week number calculation functionality can be extended to the Date object prototype:
Date.prototype.getWeekNumber = function() {
var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
var dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
return Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
};
// Usage example
var currentWeek = new Date().getWeekNumber();
console.log('Current ISO week number: ' + currentWeek);
Algorithm Details Analysis
The core logic of week number calculation involves several key steps:
Date Adjustment Phase:
var dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
This code adjusts any date to the nearest Thursday. By converting Sunday value from 0 to 7, calculation consistency is ensured. The adjustment formula guarantees accurate identification of the Thursday containing the week, regardless of the input date's day of the week.
Week Number Calculation Phase:
var weekNo = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
Here, time difference calculation is used to determine days from year start to target date, with 86400000 representing milliseconds in a day. Adding 1 ensures inclusion of the first day, dividing by 7 yields week number, and Math.ceil ensures partial weeks are correctly counted.
Boundary Case Handling
ISO week number calculation requires special attention to year boundary cases:
Cross-Year Week Handling:
// Test cross-year dates
var testDate1 = new Date('2023-12-31'); // May belong to week 1 of 2024
var testDate2 = new Date('2024-01-01'); // May belong to week 52 of 2023
var week1 = getWeekNumber(testDate1);
var week2 = getWeekNumber(testDate2);
console.log('2023-12-31:', week1); // May return [2024, 1]
console.log('2024-01-01:', week2); // May return [2023, 52]
This handling ensures correct attribution of dates at year boundaries, complying with ISO-8601 standard definitions.
Performance Optimization Considerations
For applications requiring frequent week number calculations, consider the following optimization strategies:
Calculation Result Caching:
var weekCache = {};
function getCachedWeekNumber(date) {
var key = date.toISOString().split('T')[0];
if (!weekCache[key]) {
weekCache[key] = getWeekNumber(date);
}
return weekCache[key];
}
Batch Processing Optimization:
function getWeekNumbersForRange(startDate, endDate) {
var results = [];
var current = new Date(startDate);
while (current <= endDate) {
results.push({
date: new Date(current),
week: getWeekNumber(current)
});
current.setDate(current.getDate() + 1);
}
return results;
}
Compatibility Testing and Validation
To ensure algorithm accuracy, comprehensive testing validation is necessary:
function validateWeekCalculation() {
var testCases = [
{ date: '2023-01-01', expected: [2022, 52] },
{ date: '2023-01-02', expected: [2023, 1] },
{ date: '2023-12-31', expected: [2023, 52] },
{ date: '2024-01-01', expected: [2024, 1] }
];
testCases.forEach(function(testCase) {
var result = getWeekNumber(new Date(testCase.date));
var isValid = result[0] === testCase.expected[0] &&
result[1] === testCase.expected[1];
console.log(testCase.date + ': ' + (isValid ? 'PASS' : 'FAIL'));
});
}
Practical Application Scenarios
ISO week numbers have important applications in various business scenarios:
Report Generation:
function generateWeeklyReport(startDate, endDate) {
var weeklyData = {};
var current = new Date(startDate);
while (current <= endDate) {
var weekInfo = getWeekNumber(current);
var weekKey = weekInfo[0] + '-W' + weekInfo[1].toString().padStart(2, '0');
if (!weeklyData[weekKey]) {
weeklyData[weekKey] = {
year: weekInfo[0],
week: weekInfo[1],
data: []
};
}
weeklyData[weekKey].data.push({
date: new Date(current),
// Business data...
});
current.setDate(current.getDate() + 1);
}
return weeklyData;
}
International Date Display:
function formatInternationalDate(date) {
var weekInfo = getWeekNumber(date);
return weekInfo[0] + '-W' + weekInfo[1].toString().padStart(2, '0');
}
// Output format: 2023-W52
Summary and Best Practices
Implementing accurate ISO week number calculations requires comprehensive consideration of algorithm correctness, timezone handling, and performance optimization. By using UTC methods, properly handling boundary cases, and implementing appropriate caching strategies, stable and reliable week number calculation functionality can be built. In actual projects, it is recommended to choose suitable implementation methods based on specific business requirements and conduct thorough testing validation.