【问题标题】:Outputting dates in natural language in javascript在javascript中以自然语言输出日期
【发布时间】:2022-01-25 04:12:37
【问题描述】:

我的朋友要求我做一件显然很痛苦的事情,即将日期选择器中的日期转换为自然语言,先用英语,然后再用法语,因为他是一名公证人,想要一个工具来复制/粘贴自然日期进入他的文件,这样他就不会出错。

所需的输出格式为:twenty-fourth day of January two thousand and twenty-two

我浏览了大约 8 个现有的库,但似乎没有一个用自然语言处理日历日或年。

【问题讨论】:

标签: javascript date formatting


【解决方案1】:

这样做的方法是分别转换每个日期实体。 (答案使用对Transform numbers to words in lakh / crore system 的引用将年份转换为根据您的用例修改的单词。)

var a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
var b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];



function yearInWords (num) {
    if ((num = num.toString()).length > 9) return 'overflow';
    n = ('000000000' + num).substr(-9).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/);
    if (!n) return; var str = '';
    str += (n[1] != 0) ? (a[Number(n[1])] || b[n[1][0]] + ' ' + a[n[1][1]]) + 'crore ' : '';
    str += (n[2] != 0) ? (a[Number(n[2])] || b[n[2][0]] + ' ' + a[n[2][1]]) + 'lakh ' : '';
    str += (n[3] != 0) ? (a[Number(n[3])] || b[n[3][0]] + ' ' + a[n[3][1]]) + 'thousand ' : '';
    str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
    str += (n[5] != 0) ? ((str != '') ? 'and ' : '') + (a[Number(n[5])] || b[n[5][0]] + (a[n[5][1]] ? '-' : '') + a[n[5][1]]) : '';
    return str;
}

 var days = ['first','second','third','fourth','fifth', 'sixth','seventh','eigth','ninth','tenth','eleventh','twelth','thirteenth','fouteenth','fifteenth','sixteenth','seventeen',
 'eighteenth','nineteenth', 'twentieth', 'twenty', 'thirtieth', 'thirty'];

 function dayInWords (num) {
    if(num > 31) return 'invalid day';
    if(num < 21) return days[num-1];
    if(num < 30) return days[20] + '-' + days[(num % 10)-1];
    if(num == 30) return days[21];
    return days[22] + '-' + days[(num % 10)-1];
    return str;
}

let date = new Date("01/31/2022");
let day = dayInWords(date.getDate());
let month = date.toLocaleString('default', { month: 'long' });
let year = yearInWords(date.getFullYear());
finalDateInWords = day + ' day of ' + month + ' ' + year;
console.log(finalDateInWords);

【讨论】:

    【解决方案2】:

    是的,做到了,谢谢!对最后一点做了一个快速修改,以便我可以从我的主脚本中调用它:

    function englisDate(_date){
      let date = new Date(_date);
      let day = dayInWords(date.getDate());
      let month = date.toLocaleString('default', { month: 'long' });
      let year = yearInWords(date.getFullYear());
      finalDateInWords = day + ' day of ' + month + ' ' + year;
      console.log(finalDateInWords);
      return(finalDateInWords);
    }
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案3】:

    如果您只对数字小于 10,000 的日期感兴趣,以下可能适合。

    数字到名称的映射可以被压缩,但是使映射更简单会使逻辑更复杂,对于日期,我看不出增加复杂性的意义。但它可以被清理并变得更简洁。

    部分复杂性在于确定是写数字名称还是序数(例如“一”或“第一”),以及是否以及在何处添加“和”(例如“一百零六”或“一千”和二十六”)。

    function toSpeakableDate(date = new Date()) {
      let toWord = (num, ord) => {
        let numberMap = {
         0: {name: 'zero', ordinal: 'zeroth'},
         1: {name: 'one', ordinal: 'first'}, 
         2: {name: 'two', ordinal: 'second'},
         3: {name: 'three', ordinal: 'third'}, 
         4: {name: 'four', ordinal: 'fourth'}, 
         5: {name: 'five', ordinal: 'fifth'}, 
         6: {name: 'six', ordinal: 'sixth'}, 
         7: {name: 'seven', ordinal: 'seventh'}, 
         8: {name: 'eight', ordinal: 'eighth'}, 
         9: {name: 'nine', ordinal: 'ninth'},
         10: {name: 'ten', ordinal: 'tenth'},
         11: {name: 'eleven', ordinal: 'eleventh'},
         12: {name: 'twelve', ordinal: 'twelfth'},
         13: {name: 'thirteen', ordinal: 'thirteenth'},
         14: {name: 'fourteen', ordinal: 'fourteenth'},
         15: {name: 'fifteen', ordinal: 'fifteenth'},
         16: {name: 'sixteen', ordinal: 'sixteenth'},
         17: {name: 'seventeen', ordinal: 'seventeenth'},
         18: {name: 'eighteen', ordinal: 'eighteenth'},
         19: {name: 'nineteen', ordinal: 'nineteenth'},
         20: {name: 'twenty', ordinal: 'twentyth'},
         30: {name: 'thirty', ordinal: 'thirtyth'},
         40: {name: 'fourty', ordinal: 'fourtyth'},
         50: {name: 'fifty', ordinal: 'fiftyth'},
         60: {name: 'sixty', ordinal: 'sixtyth'},
         70: {name: 'seventy', ordinal: 'sventyth'},
         80: {name: 'eighty', ordinal: 'eightyth'},
         90: {name: 'ninety', ordinal: 'ninetieth'}
        };
        
        let n = String(num);
        let text;
        
        if (n < 21) {
          text = numberMap[n][ord? 'ordinal' : 'name'];
        } else if (n < 1e2) {
          let units = n % 10;
          let tens = Math.floor(n / 10) * 10;
          text = units? `${numberMap[tens].name}-${toWord(units, ord)}` : `${numberMap[tens].ordinal}`;
        } else if (n < 1e3) {
          let hundreds = Math.floor(n / 1e2);
          let remainder = n % 1e2;
          text = `${toWord(hundreds)} hundred` +
            (remainder? ` and ${toWord(remainder)}` : ''); 
        } else if (n < 1e4) {
          let thousands = Math.floor(n / 1e3);
          let noHundreds = String(n).slice(-3,-2) == '0';
          let remainder = n % 1e3;
          text = `${toWord(thousands)} thousand` +
            `${noHundreds? ' and' : ''}` +
            (remainder? ` ${toWord(remainder)}` : ''); 
        }
        return text;
      }
      
      let fullDate = '';
      let day = toWord(date.getDate(), true);
      fullDate += day + ' day of ';
      let month = date.toLocaleString('en',{month:'long'});
      fullDate += month + ' ';
      let year = toWord(date.getFullYear());
      fullDate += year;
    
      return fullDate;
    }
    
    // Examples
    // Simple date formatter
    let f = date => date.toLocaleString('en-GB', {
     year:'numeric',month:'short',day:'2-digit'});
    
    [new Date(666,0,1),
     new Date(1215,4,31),
     new Date(),
     new Date(2222,5,13)
    ].forEach(d => console.log(f(d) + '\n' + toSpeakableDate(d)));

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 2016-04-29
      相关资源
      最近更新 更多