GithubHelp home page GithubHelp logo

scurker / currency.js Goto Github PK

View Code? Open in Web Editor NEW
3.1K 22.0 141.0 7.31 MB

A javascript library for handling currencies

Home Page: https://currency.js.org

License: MIT License

JavaScript 94.71% TypeScript 5.29%
currency-values javascript javascript-library money currency

currency.js's Introduction

currency.js logo

currency.js

Build Status Coverage Status npm gzip size

currency.js is a lightweight ~1kb javascript library for working with currency values. It was built to work around floating point issues in javascript. This talk by Bartek Szopka explains in detail why javascript has floating point issues.

currency.js works with values as integers behind the scenes, resolving some of the most basic precision problems.

2.51 + .01;                   // 2.5199999999999996
currency(2.51).add(.01);      // 2.52

2.52 - .01;                   // 2.5100000000000002
currency(2.52).subtract(.01); // 2.51

This should work for most reasonable values of currencies. As long as your currency values are less than 253 (in cents) or 90,071,992,547,409.91 you should be okay.

Features

  • 0 dependencies!
  • Immutable
  • Flexible formatting options
  • Handles any type of currency input, strings, numbers, or another currency instance

Installation

With npm:

npm install --save currency.js

With yarn:

yarn add currency.js

Via cdn:

<script src="https://unpkg.com/currency.js@~2.0.0/dist/currency.min.js"></script>

Need the latest cutting edge? All commits on master are tagged with next on npm:

npm install --save currency.js@next

Usage

Currency will accept numbers, strings, or the currency object itself as values.

currency(123);      // 123.00
currency(1.23);     // 1.23
currency("1.23")    // 1.23
currency("$12.30")  // 12.30

var value = currency("123.45");
currency(value);    // 123.45

Currency accepts decimal values (i.e. 1.23) with a default precision of 2, but can accept a minor currency unit (e.g. cents in a dollar). This will respect the precision option when parsing.

currency(123, { fromCents: true });               // 1.23
currency('123', { fromCents: true });             // 1.23
currency(123, { fromCents: true, precision: 0 }); // 123
currency(123, { fromCents: true, precision: 3 }); // 0.123

There's various arithmetic methods that help take the guesswork out of trying to resolve floating point problems.

currency(123.50).add(0.23);       // 123.73
currency(5.00).subtract(0.50);    // 4.50
currency(45.25).multiply(3);      // 135.75
currency(1.12).distribute(5);     // [0.23, 0.23, 0.22, 0.22, 0.22]

There's even a built in formatter that will automatically place comma delimiters in the right place.

currency("2,573,693.75").add("100,275.50").format();  // "$2,673,969.25"
currency("1,237.72").subtract(300).format();          // "$937.72"

You can also change the format, localizing the decimal and/or delimiter to your locale.

var euro = value => currency(value, { symbol: "€", separator: ".", decimal: "," });
euro("2.573.693,75").add("100.275,50").format();  // "€2.673.969,25"
euro("1.237,72").subtract(300).format();          // "€937,72"

Options

currency.js comes with its own set of default options conforming to USD. You can customize these according to your locale.

symbol default: $
Currency symbol included when calling currency.format().

separator default: ,
Separator dividing the number groups when calling currency.format().

decimal default: .
Decimal used when calling currency.format().

precision default: 2
Number of decimal places to store as cents.

pattern default: !#
Allows you to customize the format pattern using ! as replacement for the currency symbol and # as replacement for the currency amount.

negativePattern default: -!#
Allows you to customize the negative format pattern using ! as replacement for the currency symbol and # as replacement for the currency amount.

format default null Allows you to customize the format of the currency when calling currency.format(). format passes in the currency object as well as the options object to the function and expects a string to be returned. Use this when the provided formatting options do not meet your needs.

errorOnInvalid default: false
If an invalid value such as null or undefined is passed in, will throw an error.

increment default: null
When implementing a currency that implements rounding, setting the increment value will allow you to set the closest increment to round the display value to. currency(1.48, { increment: .05 }); // => 1.50

useVedic default: false
Formats number groupings using the Indian Numbering System, i.e. 10,00,000.00

fromCents default: false
Parse the amount value as a minor currency unit (e.g. cents in a dollar) instead of dollars.

View more examples and full documentation at https://currency.js.org.

Internationalization Examples

currency(1.23, { separator: " ", decimal: ",", symbol: "€" });

If you need to work with multiple currency values, the easiest way is to setup factory functions with your required currency settings.

const USD = value => currency(value, { symbol: "$", precision: 2 });
const JPY = value => currency(value, { symbol: "¥", precision: 0 });
const GAS = value => currency(value, { precision: 3 });

USD(1234.56).format(); // "$1,234.56"
JPY(1234.56).format(); // "¥1,235"
GAS(1234.56).format(); // "$1,234.560"

Add-ons

Other Libraries

Maybe currency.js isn't the right fit for your needs. Check out some of these other fine libraries:

License

MIT

currency.js's People

Contributors

amccloud avatar bgentry avatar charlie-s avatar chrisvariety avatar dependabot[bot] avatar greenkeeper[bot] avatar k1bs avatar kyleburton avatar luis-kaufmann-silva avatar markokeeffe avatar pvermeer avatar renovate-bot avatar renovate[bot] avatar ryanwood avatar scurker avatar sleavely avatar timfoley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

currency.js's Issues

Remove misspelled option

Right now, there's two ways to set the separator when formatting currency values. Both currency.settings.seperator and currency.settings.separator. The former should be removed in favor of the second, which will cause a breaking change for anyone that potentially updates to the newer version.

Can't format big numbers.

Example the number is '2.443233038698408e+21' and what currency.js does when currency('2.443233038698408e+21').format() the result is '2.44', that's not the correct answer!

3

Rounding error

When multiplying two numbers with different precision the rounded value is not the right one in the following case : XX.X55 with precision 2. The value returned is XX.X5 instead of XX.X6.

Here is an example:

var taxVal = currency(0.09975, {precision: 5}) 
// {intValue: 9975, value: 0.09975, s: {…}, p: 100000}

var amount = currency(180)
// {intValue: 18000, value: 180, s: {…}, p: 100}


amount.multiply(taxVal)
// {intValue: 1795, value: 17.95, s: {…}, p: 100}

The expected value would be 1796 with Banker's Rounding.

Is this the expected rounding behavior?

An in-range update of mocha is breaking the build 🚨

Version 3.4.0 of mocha just got published.

Branch Build failing 🚨
Dependency mocha
Current Version 3.3.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As mocha is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

Release Notes v3.4.0

Mocha is now moving to a quicker release schedule: when non-breaking changes are merged, a release should happen that week.

This week's highlights:

  • allowUncaught added to commandline as --allow-uncaught (and bugfixed)
  • warning-related Node flags

🎉 Enhancements

🐛 Fixes

🔩 Other

Commits

The new version differs by 9 commits0.

  • 7554b31 Add Changelog for v3.4.0
  • 9f7f7ed Add --trace-warnings flag
  • 92561c8 Add --no-warnings flag
  • ceee976 lint test/integration/fixtures/simple-reporter.js
  • dcfc094 Revert "use semistandard directly"
  • 93392dd no special case for macOS running Karma locally
  • 4d1d91d --allow-uncaught cli option
  • fb1e083 fix allowUncaught in browser
  • 4ed3fc5 Add license report and scan status

false

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Whitelist files for npm

Currently everything in the package is included for npm. Need to whitelist currency.js and currency.min.js to reduce the size in npm.

bower.json

  "main": [
    "dist/currency.js"
  ],

but dist-folder is missing

image

Rounding precision

I modified your unit test should default rounding when parsing to use var round1 = currency(1.2349) instead of current 1.234 and that caused rouding to break (not half-up).

Add Typescript definition

See #35 for a large part of the discussion, but it would be nice to have Typescript bindings so that when using currency you can infer proper usage of properties and functions.

Add explanation of .value property to README.md

It would be useful if you included an explanation of the .value and .intValue properties on the home README.md page. The .value property is an important one as it makes your library able to seamlessly replace js floating point arithmetic, using two js numbers to produce another js number without the bugs of IEEE754

An in-range update of html-minifier is breaking the build 🚨

The devDependency html-minifier was updated from 3.5.20 to 3.5.21.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

html-minifier is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Commits

The new version differs by 11 commits.

  • 5494091 Version 3.5.21
  • c6ecb90 Support <!doctypehtml> in the parser
  • c3f5168 Update build
  • f625991 Merge pull request #970 from mathiasbynens/doctype
  • cf55c51 Merge pull request #965 from mathiasbynens/fix-ampersand
  • 7e8406e Use <!doctypehtml> (without the space) where possible
  • 9b0c7cc Prevent data loss when using decodeEntities
  • df720b3 handle clean-css errors correctly (#955)
  • dcb6941 fix STDIN handling of CLI (#956)
  • 1f8df44 fix --minify-urls in CLI (#957)
  • 2d34ad5 Update README.md (#954)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

JSON.Stringify Issue

When I do something like

JSON.stringify({ value: currency(1234.56) })

The result comes back as "{"value":{"value":123456}}"

The issue is that the toString() method on the currency object is not getting called.

Formatting of negative numbers

When formatting a negative number with formatWithSymbol:true, the minus sign is placed after the currency symbol, i.e. "$-10.00". I think it's more commonly seen placed before the currency symbol, i.e. "-$10.00". Can this be changed, or at least an option added to choose where the minus sign should be placed?

Separator in decimal

currency("2573693.75755", { precision: 4 }).format();   //  2,573,693.7,576

The output is 2,573,693.7,576
For me it should be 2,573,693.7576
No separator in decimal.

Handle max/min integer values

Currently, currency.js does not handle integer values beyond the max/min possible int values. So for whatever reason if you're performing calculations in that range you could have some overflow errors.

The maximum possible value should be 253 - 1 or 9,007,199,254,740,991. There should probably be some tests around this, and the library could potentially throw an error if that number overflows. There's some additional functions available as part of the ES6 harmony draft that might be available to be used.

How to remove cents?

I have price product:
currency(product.price, { separator: ' ' }).format()
It return:
770 606.00
When I using .dollars()
It return price but dont have separator
770606
Please help me. Thank you.

"seperater" should be "separator"

You've got an option seperater for specifying the string that should separate groups of numbers (i.e. ,). That's spelled incorrectly, and should instead be separator.

I'd be happy to submit a PR with this change. Would you like to leave the old option around without documentation for compatibility reasons?

Add AMD support

Currently only CommonJS is supported, and when fixing #24 it shouldn't be too difficult to add AMD support as well.

Yarn cli update

Yarn yarn install --save currency.js

error install has been replaced with add to add new dependencies. Run yarn add currency.js instead.

Format bug

let CHY = value => currency(value, {precision: 2})
let result = CHY(99999747361065.39).format()
expected : 99,999,747,361,065.39
actual: 99,999,747,361,065.41

TypeScript import error on node

I import this package like this:

import currency from 'currency.js';
currency(1).add(1.1);

This code work fine on webpack build, but fail on node TypeError: currency_js_1.default is not a function. I use currency.js in TypeScript project.

The npm package source exports is module.exports = currency, which should be export = currency; in d.ts file. So, I think maybe we should modify the currency.d.ts , or build result.

Rounding bugs

Test: currency('1312.444445', {precision: 2})
Expected: 1312.45
Got: 1312.44

Test: currency(1312.45, {precision: 0})
Expected: 1313
Got: 1313

Test: currency('1312.45', {precision: 0})
Expected: 1313
Got: 1312

Only the second test yields a correct result! Then if I just pass the value as string instead of a number, the result is wrong!

Option to do rounding

Some currencies in common usage need some rounding. E.g. CHF when used for billing needs to be rounded to the next 0.05 value

  • 1.342 => 1.35
  • 1.3216 => 1.30

Add option to format or additional method .round to library

Add valueOf() method for returning numeric value

Consider adding a valueOf() method, to complement the current toString() method, which would return the numeric value of the currency.

Currently when comparing two currencies, they compare alphabetically (because toString() is used):

currency(20.00) > currency(10000) === true

When in fact they should be compared numerically (and the above would be === false).

Adding .valueOf() (which would just return .value) would allow for such situation.

International formatting does not display correctly

As reported by @iamjochem, formatting doesn't work correctly if you try to change the formatting values to non us-centric values (/pull/5).

currency.settings.seperator  = '.';
currency.settings.decimal    = ',';

currency(1000000.00).format();
// should return "1.000.000,00" but actually returns "1,000.000.00"

Right now, it's replacing the first decimal that matches, which causes issues if one of the settings values is a decimal.

Rounding error with precision

Hi,

It seems that rounding with option precision does not works correctly in some case:

  • currency(0.43499, { precision: 2 }) => 0.44, but 0.43 is expected
  • currency(1.354999, { precision: 2 }) => 1.36, but 1.35 is expected

Add Flow definition

Similar to #36, it would be nice to have Flow definitions for currency.js.

I'm not sure exactly how to implement the flow definition, but the typescript definition could be used for inspiration.

Add support for different precision currencies

Not all currencies have two digits after the decimals. Some have 4 digits after the decimal, some have 0 digits after the decimal, while the majority have 2 digits after the decimal.

It would be nice to have an option for the constructor top specify the precision either as a method, or during creation:

currency(2.51)  // 2.51
currency(2.51, 4)  // 2.5100, with precision option

or

currency.settings.precision(4)

Although this would change the "global" settings for all currency instances after required. It would be nice to set the formatting, decimal, separator, symbol and precision on a per usage basis (I have a site that needs to work in multiple currency formats in NodeJS, and altering the settings currently affects everything)

Many suggest that currencies be stored with 4 digits after the decimal in databases (along with the currency code in use), so maybe switching from 2 digits in the internal native format to 4 digits might also be an option.

IEEE754 bug appears at extreme precision values

I received the following results when using precision of 18 or greater.
image

image

This is obviously an extreme example which would be unlikely to cause problems in most real life scenarios, but it is a bug nonetheless.

my code:

this.settlement.total = currency(this.settlement.amount, {precision: 18}).multiply((currency(1, {precision: 18}).add((currency(this.settlement.feePercent, {precision: 18}).divide(100))))).value;

Use src files instead of dist with AVA

During the upgrade to Babel 7, it seems that AVA is no longer picking up config/rename-internal babel plugin. I don't know if this is an issue with Babel 7, or AVA but I switched to testing the dist/currency.min.js version.

The current downside is you have to always run the build step before coverage & test.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.