You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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-39 into 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 the dd/mm/yyyy format 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 + yearNum and 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 22:27:52