使用toLocaleDateString处理两位年份返回错误世纪的问题
Fixing the 2039 vs 1939 Date Conversion Quirk
Ah, I know this one! The issue here is how JavaScript's Date constructor handles two-digit years out of the box. By default, it’s hardcoded to treat years 00-69 as 2000–2069 and 70-99 as 1970–1999. That’s why your 01-APR-39 is getting bumped to 2039 instead of staying in the 1930s.
To fix this, you’ll need to take control of parsing the date components manually instead of relying on the Date constructor’s automatic (and sometimes wrong) interpretation. Here’s a straightforward approach:
Step-by-Step Solution
- Split the input string: Break
01-APR-39into day, month abbreviation, and two-digit year components. - Map the month abbreviation to a numeric value: JavaScript uses 0-indexed months (April = 3), so a simple object mapping will handle this.
- Force the correct century: Define a cutoff year (adjust based on your data) to decide whether the two-digit year belongs to the 1900s or 2000s. For your case, since 39 should be 1939, setting a cutoff of 40 makes sense (years below 40 get 1900 added, 40+ get 2000).
- Format the final date: Use
toLocaleDateString('en-GB')or build the string manually to get thedd/mm/yyyyformat you need.
Working Code Example
function convertLegacyDate(dateString) { // Split the date into day, month, year parts const [day, monthAbbr, twoDigitYear] = dateString.split('-'); // Map 3-letter month abbreviations to 0-indexed numbers const monthIndexMap = { JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11 }; const monthIndex = monthIndexMap[monthAbbr]; // Calculate the full year with correct century const cutoffYear = 40; // Adjust this based on your data's time range const yearNum = parseInt(twoDigitYear, 10); const fullYear = yearNum < cutoffYear ? 1900 + yearNum : 2000 + yearNum; // Create the date object and format to en-GB style const correctedDate = new Date(fullYear, monthIndex, parseInt(day, 10)); return correctedDate.toLocaleDateString('en-GB'); } // Test with your example console.log(convertLegacyDate('01-APR-39')); // Output: "01/04/1939"
Alternative: Manual Formatting (No Date Object)
If you want to avoid any potential edge cases with the Date object (like time zone weirdness), you can build the formatted string directly:
function convertLegacyDate(dateString) { const [day, monthAbbr, twoDigitYear] = dateString.split('-'); // Map abbreviations to 2-digit month strings const monthStringMap = { JAN: '01', FEB: '02', MAR: '03', APR: '04', MAY: '05', JUN: '06', JUL: '07', AUG: '08', SEP: '09', OCT: '10', NOV: '11', DEC: '12' }; const month = monthStringMap[monthAbbr]; // Determine full year const cutoffYear = 40; const yearNum = parseInt(twoDigitYear, 10); const fullYear = yearNum < cutoffYear ? `19${twoDigitYear}` : `20${twoDigitYear}`; // Return in dd/mm/yyyy format return `${day}/${month}/${fullYear}`; } console.log(convertLegacyDate('01-APR-39')); // Output: "01/04/1939"
Quick Tips
- Tweak the cutoff: If all your dates are from the 1900s, just set
fullYear = 1900 + yearNumand skip the cutoff check. - Add validation: If your XML data might have invalid entries (like
30-FEB-39), add checks to handle those cases gracefully.
内容的提问来源于stack exchange,提问作者silvered.dragon
相关产品推荐
相关产品推荐

