humanize-duration
Advanced tools
Comparing version 1.1.1 to 2.0.0
@@ -8,17 +8,15 @@ /* | ||
;(function() { | ||
(function() { | ||
// Start by defining the units and how many ms is in each. | ||
var UNITS = [ | ||
{ name: "year", ms: 31557600000 }, | ||
{ name: "month", ms: 2629800000 }, | ||
{ name: "week", ms: 604800000 }, | ||
{ name: "day", ms: 86400000 }, | ||
{ name: "hour", ms: 3600000 }, | ||
{ name: "minute", ms: 60000 }, | ||
{ name: "second", ms: 1000 }, | ||
{ name: "millisecond", ms: 1 } | ||
]; | ||
var UNITS = { | ||
year: 31557600000, | ||
month: 2629800000, | ||
week: 604800000, | ||
day: 86400000, | ||
hour: 3600000, | ||
minute: 60000, | ||
second: 1000, | ||
millisecond: 1 | ||
}; | ||
// Let's also define the default languages. | ||
var languages = { | ||
@@ -65,2 +63,12 @@ ca: { | ||
}, | ||
nl: { | ||
year: function() { return "jaar"; }, | ||
month: function(c) { return (c === 1) ? "maand" : "maanden"; }, | ||
week: function(c) { return (c === 1) ? "week" : "weken"; }, | ||
day: function(c) { return (c === 1) ? "dag" : "dagen"; }, | ||
hour: function() { return "uur"; }, | ||
minute: function(c) { return (c === 1) ? "minuut" : "minuten"; }, | ||
second: function(c) { return (c === 1) ? "seconde" : "seconden"; }, | ||
millisecond: function(c) { return (c === 1) ? "milliseconde" : "milliseconden"; }, | ||
}, | ||
es: { | ||
@@ -135,80 +143,49 @@ year: function(c) { return "año" + ((c !== 1) ? "s" : ""); }, | ||
millisecond: function(c) { return ["миллисекунд", "миллисекунда", "миллисекунды"][getRussianForm(c)]; } | ||
}, | ||
"zh-CN": { | ||
year: function() { return "年"; }, | ||
month: function() { return "个月"; }, | ||
week: function() { return "周"; }, | ||
day: function() { return "天"; }, | ||
hour: function() { return "小时"; }, | ||
minute: function() { return "分钟"; }, | ||
second: function() { return "秒"; }, | ||
millisecond: function() { return "毫秒"; } | ||
}, | ||
"zh-TW": { | ||
year: function() { return "年"; }, | ||
month: function() { return "個月"; }, | ||
week: function() { return "周"; }, | ||
day: function() { return "天"; }, | ||
hour: function() { return "小時"; }, | ||
minute: function() { return "分鐘"; }, | ||
second: function() { return "秒"; }, | ||
millisecond: function() { return "毫秒"; } | ||
} | ||
}; | ||
// Internal helper function for Polish language. | ||
function getPolishForm(c) { | ||
if (c === 1) { | ||
return 0; | ||
} else if (Math.floor(c) !== c) { | ||
return 1; | ||
} else if (2 <= c % 10 && c % 10 <= 4 && !(10 < c % 100 && c % 100 < 20)) { | ||
return 2; | ||
} else { | ||
return 3; | ||
} | ||
} | ||
// You can create a humanizer, which returns a function with defaults | ||
// parameters. | ||
function humanizer(passedOptions) { | ||
// Internal helper function for Russian language. | ||
function getRussianForm(c) { | ||
if (Math.floor(c) !== c) { | ||
return 2; | ||
} else if (c === 0 || (c >= 5 && c <= 20) || (c % 10 >= 5 && c % 10 <= 9) || (c % 10 === 0) ) { | ||
return 0; | ||
} else if (c === 1 || c % 10 === 1) { | ||
return 1; | ||
} else if (c > 1) { | ||
return 2; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
var result = function humanizer(ms, passedOptions) { | ||
var options = extend({}, result, passedOptions || {}); | ||
return doHumanization(ms, options); | ||
}; | ||
// Internal utility function for rendering the strings. | ||
// render(1, "minute") == "1 minute" | ||
// render(12, "hour") == "12 hours" | ||
// render(2, "hour", "es") == "2 horas" | ||
function render(count, word, language) { | ||
var dictionary = languages[language || humanizeDuration.language]; | ||
if (!dictionary) { | ||
throw new Error("Language " + language + " not defined"); | ||
} | ||
return count + " " + dictionary[word](count); | ||
} | ||
extend(result, { | ||
language: "en", | ||
delimiter: ", ", | ||
units: [ | ||
"year", | ||
"month", | ||
"week", | ||
"day", | ||
"hour", | ||
"minute", | ||
"second" | ||
], | ||
languages: {} | ||
}, passedOptions); | ||
// Grab the components. | ||
function componentsOf(total, language) { | ||
var result = { total: {} }; | ||
// Make sure we have positive numbers. | ||
// Has the nice sideffect of turning Number objects into primitives. | ||
total = Math.abs(total); | ||
var ms = total; | ||
var unit, unitName, unitTotal, unitCount; | ||
for (var i = 0, len = UNITS.length; i < len; i ++) { | ||
// Store the current unit. | ||
unit = UNITS[i]; | ||
unitName = unit.name + "s"; | ||
// What are the totals and the rest? | ||
if (unitName === "milliseconds") { | ||
unitCount = ms / unit.ms; | ||
unitTotal = total / unit.ms; | ||
} else { | ||
unitCount = Math.floor(ms / unit.ms); | ||
unitTotal = Math.floor(total / unit.ms); | ||
} | ||
// Put them in the result. | ||
result[unitName] = render(unitCount, unit.name, language); | ||
result.total[unitName] = render(unitTotal, unit.name, language); | ||
// Lower the number of milliseconds. | ||
ms -= unitCount * unit.ms; | ||
} | ||
return result; | ||
@@ -218,5 +195,11 @@ | ||
// The main function. | ||
function humanizeDuration(ms, language) { | ||
// The main function is just a wrapper around a default humanizer. | ||
var defaultHumanizer = humanizer({}); | ||
function humanizeDuration(ms, passedOptions) { | ||
return defaultHumanizer(ms, passedOptions); | ||
} | ||
// doHumanization does the bulk of the work. | ||
function doHumanization(ms, options) { | ||
// Make sure we have a positive number. | ||
@@ -226,63 +209,102 @@ // Has the nice sideffect of turning Number objects into primitives. | ||
// Humanizing zero, I see. | ||
if (ms === 0) | ||
if (ms === 0) { | ||
return "0"; | ||
} | ||
// We'll put everything in an array and turn that into a string at the end. | ||
var dictionary = options.languages[options.language] || languages[options.language]; | ||
if (!dictionary) { | ||
throw new Error("No language " + dictionary + "."); | ||
} | ||
var result = []; | ||
// Start at the top and keep removing units, bit by bit. | ||
var unit, unitCount, mightBeHalfUnit; | ||
for (var i = 0, len = UNITS.length; i < len; i ++) { | ||
var unitName, unitMS, unitCount, mightBeHalfUnit; | ||
for (var i = 0, len = options.units.length; i < len; i ++) { | ||
// Store the current unit. | ||
unit = UNITS[i]; | ||
unitName = options.units[i]; | ||
if (unitName[unitName.length - 1] === "s") { // strip plurals | ||
unitName = unitName.substring(0, unitName.length - 1); | ||
} | ||
unitMS = UNITS[unitName]; | ||
// If it's a half-unit interval, we're done. | ||
if (result.length === 0) { | ||
mightBeHalfUnit = (ms / unit.ms) * 2; | ||
if (mightBeHalfUnit === Math.floor(mightBeHalfUnit)) | ||
return render(mightBeHalfUnit / 2, unit.name, language); | ||
mightBeHalfUnit = (ms / unitMS) * 2; | ||
if (mightBeHalfUnit === Math.floor(mightBeHalfUnit)) { | ||
return render(mightBeHalfUnit / 2, unitName, dictionary); | ||
} | ||
} | ||
// What's the number of full units we can fit? | ||
if (unit.name === "millisecond") { | ||
unitCount = ms / unit.ms; | ||
if ((i + 1) === len) { | ||
unitCount = ms / unitMS; | ||
} else { | ||
unitCount = Math.floor(ms / unit.ms); | ||
unitCount = Math.floor(ms / unitMS); | ||
} | ||
// Add the string. | ||
if (unitCount) | ||
result.push(render(unitCount, unit.name, language)); | ||
if (unitCount) { | ||
result.push(render(unitCount, unitName, dictionary)); | ||
} | ||
// Remove what we just figured out. | ||
ms -= unitCount * unit.ms; | ||
ms -= unitCount * unitMS; | ||
} | ||
// All done! Turn the array into a string. | ||
return result.join(", "); | ||
return result.join(options.delimiter); | ||
} | ||
// How do you add a new language? | ||
humanizeDuration.addLanguage = function addLanguage(name, definition) { | ||
if (languages[name]) { | ||
throw new Error("Language " + name + " already defined. If you think this " + | ||
"is an error, please submit a patch!"); | ||
humanizeDuration.humanizer = humanizer; | ||
if ((typeof module !== "undefined") && (module.exports)) { | ||
module.exports = humanizeDuration; | ||
} else { | ||
this.humanizeDuration = humanizeDuration; | ||
} | ||
function render(count, word, dictionary) { | ||
return count + " " + dictionary[word](count); | ||
} | ||
function extend(destination) { | ||
var source; | ||
for (var i = 1; i < arguments.length; i ++) { | ||
source = arguments[i]; | ||
for (var prop in source) { | ||
destination[prop] = source[prop]; | ||
} | ||
} | ||
languages[name] = definition; | ||
}; | ||
return destination; | ||
} | ||
// What's the default language? | ||
humanizeDuration.language = "en"; | ||
// Internal helper function for Polish language. | ||
function getPolishForm(c) { | ||
if (c === 1) { | ||
return 0; | ||
} else if (Math.floor(c) !== c) { | ||
return 1; | ||
} else if (2 <= c % 10 && c % 10 <= 4 && !(10 < c % 100 && c % 100 < 20)) { | ||
return 2; | ||
} else { | ||
return 3; | ||
} | ||
} | ||
// Export this baby. | ||
humanizeDuration.componentsOf = componentsOf; | ||
if ((typeof module !== "undefined") && (module.exports)) | ||
module.exports = humanizeDuration; | ||
else | ||
this.humanizeDuration = humanizeDuration; | ||
// Internal helper function for Russian language. | ||
function getRussianForm(c) { | ||
if (Math.floor(c) !== c) { | ||
return 2; | ||
} else if (c === 0 || (c >= 5 && c <= 20) || (c % 10 >= 5 && c % 10 <= 9) || (c % 10 === 0) ) { | ||
return 0; | ||
} else if (c === 1 || c % 10 === 1) { | ||
return 1; | ||
} else if (c > 1) { | ||
return 2; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
})(); |
@@ -8,6 +8,8 @@ { | ||
"Peter Rekdal Sunde (https://github.com/peters)", | ||
"Michał Janiec (https://github.com/mjjaniec)" | ||
"Michał Janiec (https://github.com/mjjaniec)", | ||
"Eileen Li (https://github.com/eileen3)" | ||
], | ||
"version": "1.1.1", | ||
"description": "Convert millisecond durations to English or many other languages.", | ||
"version": "2.0.0", | ||
"description": "Convert millisecond durations to English and many other languages.", | ||
"homepage": "https://github.com/EvanHahn/HumanizeDuration.js", | ||
"main": "humanize-duration.js", | ||
@@ -19,7 +21,8 @@ "scripts": { | ||
"devDependencies": { | ||
"chai": "1.9.x", | ||
"coffee-script": "1.7.x", | ||
"jshint": "2.5.x", | ||
"mocha": "1.20.x", | ||
"sugar": "1.4.x" | ||
"chai": "^1.9.x", | ||
"coffee-script": "^1.7.x", | ||
"jshint": "^2.5.x", | ||
"mocha": "^1.21.x", | ||
"sinon": "^1.10.3", | ||
"sugar": "^1.4.x" | ||
}, | ||
@@ -50,18 +53,23 @@ "keywords": [ | ||
"camelcase": true, | ||
"curly": false, | ||
"eqeqeq": false, | ||
"es3": true, | ||
"curly": true, | ||
"eqeqeq": true, | ||
"eqnull": true, | ||
"es3": false, | ||
"forin": false, | ||
"freeze": true, | ||
"immed": true, | ||
"indent": 2, | ||
"latedef": true, | ||
"maxdepth": 6, | ||
"maxparams": 5, | ||
"newcap": true, | ||
"noarg": true, | ||
"noempty": true, | ||
"nonbsp": true, | ||
"nonew": true, | ||
"plusplus": false, | ||
"quotmark": true, | ||
"quotmark": "double", | ||
"strict": false, | ||
"undef": true, | ||
"unused": true, | ||
"strict": false, | ||
"trailing": true, | ||
"predef": [ | ||
@@ -68,0 +76,0 @@ "module" |
@@ -9,54 +9,72 @@ Humanize Duration | ||
Usage | ||
----- | ||
Basic usage | ||
----------- | ||
To use it in the browser: | ||
This package is available as *humanize-duration* in Node and Bower. You can also include the JavaScript in the browser. | ||
<script src="humanize-duration.js"></script> | ||
<script> | ||
humanizeDuration(12000); | ||
</script> | ||
In the browser: | ||
To use in Node or Browserify (after installing [the package](https://npmjs.org/package/humanize-duration)): | ||
```html | ||
<script src="humanize-duration.js"></script> | ||
<script> | ||
humanizeDuration(12000); | ||
</script> | ||
``` | ||
var humanizeDuration = require("humanize-duration"); | ||
humanizeDuration(12000); | ||
In Node or Browserify: | ||
Also available for Bower as *humanize-duration*. | ||
```js | ||
var humanizeDuration = require("humanize-duration"); | ||
humanizeDuration(12000); | ||
``` | ||
Here's some basic usage: | ||
Usage | ||
----- | ||
humanizeDuration(1) // "1 millisecond" | ||
humanizeDuration(3000) // "3 seconds" | ||
humanizeDuration(2012) // "2 seconds, 12 milliseconds" | ||
humanizeDuration(97320000) // "1 day, 3 hours, 2 minutes" | ||
By default, Humanize Duration will humanize down to the second, and will return a decimal for the smallest unit. It will humanize in English by default. | ||
You can also change the language: | ||
```js | ||
humanizeDuration(3000) // "3 seconds" | ||
humanizeDuration(2015) // "2.25 seconds" | ||
humanizeDuration(97320000) // "1 day, 3 hours, 2 minutes" | ||
``` | ||
humanizeDuration(3000, "es") // "3 segundos" | ||
You can change the settings by passing options as the second argument: | ||
humanizeDuration.language = "fr" // change language to French | ||
humanizeDuration(3000) // "3 secondes" | ||
humanizeDuration(5000, "ko") // "5 초" | ||
humanizeDuration.language = "en" // change language back to English | ||
```js | ||
humanizeDuration(3000, { language: "es" }) // "3 segundos" | ||
humanizeDuration(5000, { language: "ko" }) // "5 초" | ||
You can also get the components of the humanizization, using `componentsOf`: | ||
humanizeDuration(22140000, { delimiter: " and " }) // "6 hours and 9 minutes" | ||
humanizeDuration(22140000, { delimiter: "--" }) // "6 hours--9 minutes" | ||
var components = humanizeDuration.componentsOf(97320000); | ||
// components.days == "1 day" | ||
// components.total.days == "1 day" | ||
// components.hours == "3 hours" | ||
// components.total.hours == "27 hours" | ||
// components.seconds == "0 seconds" | ||
// components.total.seconds == "97320 seconds" | ||
humanizeDuration(3600000, { units: ["hours"] }) // 1 hour | ||
humanizeDuration(3600000, { units: ["days", "hours"] }) // 1 hour | ||
humanizeDuration(3600000, { units: ["minutes"] }) // 60 minutes | ||
Some edge cases: | ||
humanizeDuration(3600000, { | ||
language: "es", | ||
units: ["minutes"] | ||
}) | ||
// 60 minutos | ||
``` | ||
humanizeDuration(12.34) // "12.34 milliseconds" | ||
humanizeDuration(-567) // "567 milliseconds", ignores negative numbers | ||
### Humanizers | ||
humanizeDuration(new Number(8910)) // works as normal | ||
If you find yourself setting same options over and over again, you can create a *humanizer* that changes the defaults, which you can still override later. | ||
```js | ||
var spanishHumanizer = humanizeDuration.humanizer({ | ||
language: "es", | ||
units: ["years", "months", "days"] | ||
}); | ||
spanishHumanizer(71177400000) // "2 años, 3 meses, 2 días" | ||
spanishHumanizer(71177400000, { units: ["days", "hours"] }) // "823 días, 19.5 horas" | ||
``` | ||
Internally, the main `humanizeDuration` function is just a wrapper around a humanizer. | ||
Supported languages | ||
------------------- | ||
-------------------- | ||
@@ -66,3 +84,6 @@ Humanize Duration supports the following languages: | ||
* Catalan (ca) | ||
* Chinese, simplified (zh-CN) | ||
* Chinese, traditional (zh-TW) | ||
* Danish (da) | ||
* Dutch (nl) | ||
* English (en) | ||
@@ -75,4 +96,4 @@ * French (fr) | ||
* Portuguese (pt) | ||
* Russian (ru) | ||
* Spanish (es) | ||
* Russian (ru) | ||
@@ -82,6 +103,4 @@ Credits | ||
Lovingly made by [Evan Hahn](http://evanhahn.com/) with language support by [Martin Prins](https://github.com/magarcia). Thanks to [Filipi Siqueira](https://github.com/filipi777) for Portuguese support, [Peter Rekdal Sunde](https://github.com/peters) for Norwegian support, and [Michał Janiec](https://github.com/mjjaniec) for Polish support. | ||
Lovingly made by [Evan Hahn](http://evanhahn.com/) with language support by [Martin Prins](https://github.com/magarcia). Thanks to [Filipi Siqueira](https://github.com/filipi777) for Portuguese support, [Peter Rekdal Sunde](https://github.com/peters) for Norwegian support, [Michał Janiec](https://github.com/mjjaniec) for Polish support, and [Eileen Li](https://github.com/eileen3) for Chinese support. | ||
Licensed under the WTFPL, so you can do whatever you want. | ||
Enjoy! | ||
Licensed under the WTFPL, so you can do whatever you want. Enjoy! |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
0
103
18063
6
8
274
1