Skip to content

Commit

Permalink
Merge pull request #1 from LanceTurri/develop
Browse files Browse the repository at this point in the history
Merging develop to master.
  • Loading branch information
LanceTurri committed Sep 5, 2017
2 parents a03e1f9 + c04cc8c commit eabe17d
Show file tree
Hide file tree
Showing 17 changed files with 2,681 additions and 229 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test*
11 changes: 11 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "airbnb-base",
"plugins": [
"import"
],
"rules": {
"arrow-body-style": "off",
"indent": "off",
"no-console": "off"
}
}
54 changes: 54 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@

# Created by https://www.gitignore.io/api/node,macos,windows

### macOS ###
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### Node ###
# Logs
logs
*.log
Expand Down Expand Up @@ -57,3 +88,26 @@ typings/
# dotenv environment variables file
.env


### Windows ###
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db

# Folder config file
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msm
*.msp

# Windows shortcuts
*.lnk

# End of https://www.gitignore.io/api/node,macos,windows
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
language: node_js
node_js:
- "8"
after_success:
- npm run coveralls
47 changes: 45 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,45 @@
# date-translator
Translates dates into sentence format.
![date-convert](./images/logo.png)

# Sentence Format Date Converter

[![Build Status](https://travis-ci.org/LanceTurri/date-convert.svg?branch=develop)](https://travis-ci.org/LanceTurri/date-convert)
[![Coverage Status](https://coveralls.io/repos/github/LanceTurri/date-convert/badge.svg?branch=develop)](https://coveralls.io/github/LanceTurri/date-convert?branch=develop)

This library is meant for applications to take dates in a standard format (`string` or `Date object`) and convert them into human readable, sentence format. It's especially useful for ADA optimizations since not all screen readers handle date shorthand very well.

## Installation

Install via npm:

```sh
$ npm install date-convert
```

Or via yarn:

```sh
$ yarn add date-convert
```

## Translate the Dates!
The main function in this library will take any string date or Date object and convert it to a sentence. This is an example of how to use it:

```javascript
const convertDate = require('date-convert');

convertDate("2015-03-25") // => 'March twenty fifth, two thousand fifteen'
```

Any format that can be read by the Date constructor will be able to be converted. Here are some common formats:

```javascript
convertDate('2010-03-25') // => 'March twenty fifth, two thousand ten'
convertDate('07/04/1776') // => 'July fourth, seventeen seventy six'
convertDate('August 29 2456') // => 'August twenty ninth, two thousand fifty six'
convertDate('01/01/2000') // => 'January first, two thousand'
convertDate('Tuesday March 15, 462') // => 'March fifteenth, four hundred sixty two'
```

## License

Copyright Lance Turri. Released under the terms of the MIT license.
35 changes: 35 additions & 0 deletions core/convert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const parseDate = require('../lib/parseDate');
const dateStrings = require('./dateStrings');

const centuries = require('../lib/centuries');
const decades = require('../lib/decades');
const hundreds = require('../lib/hundreds');
const thousands = require('../lib/thousands');

module.exports = (date) => {
// We need to sanitize the date by first creating a new date and then getting the individual values for day, month, & year.
let dateMap = parseDate(date);
let stringifiedYear = dateMap.year.toString();

// 10/23/1945 => October twenty third nineteen fourty five
let month = dateStrings.months[dateMap.month];
let day = dateStrings.ordinals[dateMap.day];
let year = '';

if (dateMap.year % 100 === 0) {
// Then this is a year to be suffixed with thousand (e.g. 2000) or with a hundred (e.g. 1900)
year = centuries(stringifiedYear);
} else {
if (dateMap.year >= 1000) {
year += thousands(stringifiedYear);
}

if (dateMap.year >= 99) {
year += hundreds(stringifiedYear);
}

year += decades(stringifiedYear);
}

return `${month} ${day}, ${year}`;
};
14 changes: 14 additions & 0 deletions core/dateStrings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
months: [
'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'
],
ordinals: [
'', 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eigth', 'ninth', 'tenth', 'eleventh', 'twelvth', 'thirteenth', 'fourteenth', 'fifteenth', 'sixteenth', 'seventeenth', 'eighteenth', 'nineteenth', 'twentieth', 'twenty first', 'twenty second', 'twenty third', 'twenty fourth', 'twenty fifth', 'twenty sixth', 'twenty seventh', 'twenty eight', 'twenty nine', 'thirtieth', 'thirty first'
],
tens: [
'', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
],
ones: [
'', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
]
};
Binary file added images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions lib/centuries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const dateStrings = require('../core/dateStrings');

module.exports = (year) => {
if (year % 1000 === 0) {
// Then this is a year to be suffixed with thousand. EX: 2000, 5000, 17000, etc.
let firstDigit = parseInt(year.charAt(0));

return `${dateStrings.ones[firstDigit]} thousand`;
} else {
// Then this is a year that needs to be suffixed with hundred. EX: 1500, 1900, etc.
let firstTwoDigits = parseInt(year.slice(0, 2));

return `${dateStrings.ones[firstTwoDigits]} hundred`;
}
};
25 changes: 25 additions & 0 deletions lib/decades.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const dateStrings = require('../core/dateStrings');

module.exports = (year) => {
let decade = null;

if (year.length === 4) {
decade = parseInt(year.slice(2));
} else {
decade = parseInt(year.slice(1));
}

if (decade === 0) {
// 1900
return ``;
} else if (decade < 20) {
// 2019
return `${dateStrings.ones[decade]}`;
}

// 29 / 10 => parseInt(2.9) => 2
let tensDigit = parseInt(decade / 10);
let onesDigit = decade % 10;

return `${dateStrings.tens[tensDigit]} ${dateStrings.ones[onesDigit]}`;
};
25 changes: 25 additions & 0 deletions lib/hundreds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const dateStrings = require('../core/dateStrings');

module.exports = (year) => {
let frontPair = null;
let hundredDigit = null;

if (year.length === 4) {
frontPair = parseInt(year.slice(0, 2));
hundredDigit = parseInt(year.charAt(1));
} else {
// Three digit year - 465
frontPair = parseInt(year.slice(0, 1));
hundredDigit = parseInt(year.charAt(0));
}

if (hundredDigit === 0) {
// 1000
return ``;
} else if (frontPair < 20) {
// 1900
return `${dateStrings.ones[frontPair]} hundred `;
}

return `${dateStrings.ones[hundredDigit]} hundred `;
};
25 changes: 25 additions & 0 deletions lib/parseDate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = (dateInput) => {
switch (typeof dateInput) {
// String will be a standard input, number is most likely a UTC date.
case 'string':
case 'number':
dateInput = new Date(dateInput);
break;

default:
// We assume this is already a Date object.
break;
}

const dateMap = {
day: dateInput.getUTCDate(),
month: dateInput.getUTCMonth(),
year: dateInput.getUTCFullYear(),
};

if (parseInt(dateMap.year, 10) >= 9999) {
throw new Error('9999 CE is the latest supported date.');
}

return dateMap;
};
12 changes: 12 additions & 0 deletions lib/thousands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const dateStrings = require('../core/dateStrings');

module.exports = (year) => {
let frontPair = parseInt(year.slice(0, 2));
let thousandDigit = parseInt(year.charAt(0));

if (frontPair < 20) {
return '';
}

return `${dateStrings.ones[thousandDigit]} thousand `;
};
33 changes: 23 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
{
"name": "date-translator",
"version": "0.0.1",
"description": "Translate a Date to Human Readable Formats",
"main": "index.js",
"scripts": {
"test": "mocha"
},
"name": "date-convert",
"version": "0.1.1",
"description": "Convert a Date into a human readable sentence.",
"main": "./core/convert.js",
"keywords": [
"ada",
"convert",
"date",
"javascript",
"readable",
"sentences"
],
"author": "Lance Turri",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/LanceTurri/date-translator"
},
"scripts": {
"test": "nyc --reporter=html --reporter=text mocha",
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls"
},
"dependencies": {},
"devDependencies": {
"eslint": "^3.16.1",
"mocha": "^3.2.0"
"coveralls": "^2.13.1",
"eslint": "^4.5.0",
"eslint-config-airbnb-base": "^12.0.0",
"eslint-plugin-import": "^2.7.0",
"mocha": "^3.5.0",
"mocha-lcov-reporter": "^1.3.0",
"nyc": "^11.1.0"
}
}
Loading

0 comments on commit eabe17d

Please sign in to comment.