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)));