diff --git a/docs/CNAME b/docs/CNAME index 0161aed..61bea12 100644 --- a/docs/CNAME +++ b/docs/CNAME @@ -1 +1 @@ -numerica.js.org +numerica.js.org diff --git a/docs/assets/navigation.js b/docs/assets/navigation.js index 62baa13..a9d924c 100644 --- a/docs/assets/navigation.js +++ b/docs/assets/navigation.js @@ -1 +1 @@ -window.navigationData = "eJyNj8sOgjAQRf9l1kR8G9npQhe6MiYujItBRm0slLQjkRj/3QRfoKW67bnnpLO+ANOZIYC52qIk8CBFPkAAnKdk/Ptr48CxBA+OIokgaDeHg1avffU+3Bnldn1G+a+CLIbm7WeoBYaSjP9A1UKnLO+JP3+/OyVbFiox/gtWA/1uKWBcAfNHgNUoDDVlApkiW6QycIbGaKzfuBOnOtFYjO36kzoTU61Oad0JD+gMLEgii4yWIq45o7xwp1SMNbcUyCmvlI6MXS7Ql7y5AbSxB7s=" \ No newline at end of file +window.navigationData = "eJyNj81uwjAQBt9lz1HDTwsityIEh/RUIfWAOGzItrFw4sjeRERV373CAZpQx+3V883Iu/sEphNDBC/qgJIggBI5gwi4KcmE7etDxrmEAI6iSCGajBbz8dPkK7hzY2rcekzNXwVph+bHr1ELTCSZ8IL6hWlX/iC+//17VRxYqMKEN9gPzB47AeMLmH8EWD0niaZaIFPqivQG3tASjfMbLfGqK+QB9Uy86lqjHbv1K/UmNlpV5dD1F+gNvJJEFjVtRT5wRnfhT6kcB26xyCu/KZ0at2zRL3n/DfqZG2g=" \ No newline at end of file diff --git a/docs/assets/search.js b/docs/assets/search.js index f6bbcbe..e24cfa1 100644 --- a/docs/assets/search.js +++ b/docs/assets/search.js @@ -1 +1 @@ -window.searchData = "eJyVlc2OmzAURt/lrq0k5h9208VU1XRVVe3CQpUDzgwawBF2Mo0Q715hSAxjN3J2yNfngK3vcnvo+IeAjPTwXrUlZN4ujXHoIWhpwyCD77ygNQMEp66GDOTlyMR2Wty8yaYGBEVNhWACMoAB3fe8sItV9cIud22+FtUKEDfNmXYV3ddMbOfKXVEU3ESvTH463OHUFrLirdjeaq4ycUcmHpVJ/rTfd+xcUclKi3BVd5d+ocL2eVPBXfPcUUVaVdeiu+5rx0/H/xxzrrnLfrCayurMflaN/ajLDQ9oeUPt51UVd9Fv3pXCKlIVmyhHULUl+wtZD2fWifHmM/A2/iYFBIeK1eXYv9M7EBS8aVgrAUHJi5N6zOdtv1gheTdunnZvd4DIDnl4E6ZhniNyhVVBLVwdekWBGBDBNhAbIF6BHiDi2UDPAL0V6AMivg30DdBfgQEgEtjAwACDFRgCIqENDA0wXIERIBLZwMgAoxUYAyKxDYwNMF6BCSCS2MDEAJMVmAIiqQ1MDTBdB2DMA7ZmB5vhwZ/So+Jjz48lQNOSaoMz6yQrv03tQMj4C6/nv24Pf+Y28a/91oMPWT8Muimyflj0xVgbX2Uqdlqxe0DxPk43bcHagh+wiKXD0w7PySFsVxJoS+BkkZwuJ5A2hdoUOpr2auxoRaQVkaPicBs5WhNrTeyoeb2OGm1JtCVxtHTzCJFqxmhVqlWpq2qaK4vILJKH3aIn+cc0VBaWZfIcopcjOFZHVlctg4zkw/AP3MhCiQ=="; \ No newline at end of file +window.searchData = "eJyVlc2OmzAURt/lrq0k5h92rapW1XRVVe3CiioHnCkawJHtZDpCvHuFITGM3cjZIV+fA7a+y+1B8FcJBenhpe4qKIJdnuI4QNDRlkEB33hJGwYIzqKBAtTbicnttLj5o9oGEJQNlZJJKAAGdN/zxN6cqif2dtcWGlGjAXnTXKio6aFhcjtX7oqS6CZ6Zurd4Y7nrlQ17+T2VvOVyTsy+ahM8Q+Hg2CXmipWOYSrur/0I5Wuz5sK/ppPVLk1Y8Ff81lQTTpV16K/7ovg59N/bmuu+cu+s4aq+sJ+1K37qMsND2h5S93n1RV/0S8uKukU6YpLtEdQdxX7C0UPFybkePMFBJtwkwOCY82aavwNTO9AUPK2ZZ0CBBUvz/pxP2/7yUrFxbh52r3dASI7FASbMEz2e0SusC7ohavDrGgQAyLYBWILxCswAEQCFxhYYLACQ0AkdIGhBYYrMAJEIhcYWWC0AmNAJHaBsQXGKzABRBIXmFhgsgJTQCR1gakFpiswA0QyF5hZYLYCc0Akd4G5BebrAIx5wM7sYDs8+F16dHzc+XEEaJ0gPOYCOzOE7RDNS7qHLkwoVn2deomQcYw085+/h99zj4XXZu0hhKIfBtNRRT8smmqsja+yFTuj2D2geBknrLFgY8EPWOTSERhH4OWQriuJjCXysihOl1PQmGJjij1NBz36jCIxisRTUemxZxSpUaSeiuNt5BlNZjSZp+b5OuqMJTeW3NMi5hGm9IxbJGYRPOyXPMXFNNkWlmXw/JKn+Os01haWRfSwR/b2CE71iTV1x6Ag+2H4Bxb0ga0="; \ No newline at end of file diff --git a/docs/functions/getLocale.html b/docs/functions/getLocale.html index 54e69e4..d268713 100644 --- a/docs/functions/getLocale.html +++ b/docs/functions/getLocale.html @@ -1 +1 @@ -getLocale | numerica
numerica
    Preparing search index...

    Function getLocale

    • Parameters

      • key: string = currentLocaleKey

      Returns {
          key: NormalizedLocale;
          object: {
              currency: { position: string; spacing: boolean; symbol: string };
              digits: string[];
              direction: string;
              language: string;
              name: string;
              number: {
                  decimal: string;
                  grouping: number;
                  infinity: string;
                  nan: string;
                  negative_sign: string;
                  separator: string;
              };
          };
      }

    +getLocale | numerica
    numerica
      Preparing search index...

      Function getLocale

      • Parameters

        • key: string = currentLocaleKey

        Returns {
            key: NormalizedLocale;
            object: {
                currency: { position: string; spacing: boolean; symbol: string };
                date: {
                    format: { full: string; long: string; medium: string; short: string };
                    names: {
                        months: string[];
                        short_months: string[];
                        short_weekdays: string[];
                        weekdays: string[];
                    };
                };
                digits: string[];
                direction: string;
                language: string;
                name: string;
                number: {
                    decimal: string;
                    grouping: number;
                    infinity: string;
                    nan: string;
                    negative_sign: string;
                    ordinal_suffixes: string[];
                    separator: string;
                };
            };
        }

      diff --git a/docs/functions/setLocale.html b/docs/functions/setLocale.html index c0f715b..d761ace 100644 --- a/docs/functions/setLocale.html +++ b/docs/functions/setLocale.html @@ -1 +1 @@ -setLocale | numerica
      numerica
        Preparing search index...

        Function setLocale

        • Parameters

          • loc: string

          Returns void

        +setLocale | numerica
        numerica
          Preparing search index...

          Function setLocale

          • Parameters

            • loc: string

            Returns void

          diff --git a/docs/functions/toAbbreviated.html b/docs/functions/toAbbreviated.html index a1c8733..63d4bf7 100644 --- a/docs/functions/toAbbreviated.html +++ b/docs/functions/toAbbreviated.html @@ -7,4 +7,4 @@
          toAbbreviated(1500)           // "1.5k"
          toAbbreviated(2500000) // "2.5m"
          toAbbreviated(1000000, {decimals: 2, trim: true}) // "1m"
          toAbbreviated(1000000, {decimals: 2, trim: false}) // "1.00m"
          toAbbreviated(1234567, {decimals: 0}) // "1m"
          toAbbreviated(500) // "500"
          toAbbreviated(-3400) // "-3.4k"
          -
          +
          diff --git a/docs/functions/toBase.html b/docs/functions/toBase.html index 4cf3076..b08dab9 100644 --- a/docs/functions/toBase.html +++ b/docs/functions/toBase.html @@ -9,4 +9,4 @@
          // Integer conversions
          toBase(255, 16) // "FF" (decimal to hexadecimal)
          toBase(255, 2) // "11111111" (decimal to binary)
          toBase('FF', 10, { from: 16 }) // "255" (hexadecimal to decimal)
          toBase('1010', 10, { from: 2 }) // "10" (binary to decimal)
          toBase(100, 36) // "2S" (decimal to base-36)
          toBase(-42, 16) // "-2A" (negative numbers supported)

          // Fractional conversions
          toBase(10.5, 16) // "A.8" (decimal to hexadecimal with fractional part)
          toBase(10.75, 2) // "1010.11" (decimal to binary with fractional part)
          toBase('A.8', 10, { from: 16 }) // "10.5" (hexadecimal with fraction to decimal)
          toBase('-2A.4', 10, { from: 16 }) // "-42.25" (negative fractional conversion)
          -
          +
          diff --git a/docs/functions/toDate.html b/docs/functions/toDate.html new file mode 100644 index 0000000..300b9a4 --- /dev/null +++ b/docs/functions/toDate.html @@ -0,0 +1,31 @@ +toDate | numerica
          numerica
            Preparing search index...

            Function toDate

            • Formats a Date object into a localized string representation.

              +

              Parameters

              • date: Date

                The Date object to format

                +
              • options: Options

                Configuration options

                +
                • locale

                  The locale/language to use for formatting (e.g., "en", "de", "ar")

                  +
                • format

                  The format pattern or preset ("short", "medium", "long", "full", or custom pattern)

                  +
                • timezone

                  The timezone to use (default: "UTC+0")

                  +

              Returns string

              The formatted date string according to the specified locale and format

              +

              Supported format tokens:

              +
                +
              • YYYY - 4-digit year
              • +
              • YY - 2-digit year
              • +
              • MMMM - Full month name
              • +
              • MMM - Short month name
              • +
              • MM - 2-digit month (01-12)
              • +
              • M - 1-digit month (1-12)
              • +
              • DDDD - Full weekday name
              • +
              • DDD - Short weekday name
              • +
              • DD - 2-digit day (01-31)
              • +
              • D - 1-digit day (1-31)
              • +
              • Do - Day with ordinal suffix (1st, 2nd, 3rd)
              • +
              • HH - 2-digit hour (00-23)
              • +
              • H - 1-digit hour (0-23)
              • +
              • mm - 2-digit minute (00-59)
              • +
              • m - 1-digit minute (0-59)
              • +
              • ss - 2-digit second (00-59)
              • +
              • s - 1-digit second (0-59)
              • +
              +
              toDate(new Date()) // Uses default locale and short format
              toDate(new Date(), {locale: "de"}) // "12.11.2025" (German format)
              toDate(new Date(), {format: "YYYY-MM-DD"}) // "2025-11-12" (ISO format)
              toDate(new Date(), {locale: "en", format: "DDDD, MMMM Do, YYYY"}) // "Wednesday, November 12th, 2025"
              toDate(new Date(), {locale: "ar", format: "DD/MM/YYYY HH:mm"}) // "١٢/١١/٢٠٢٥ ١٤:٣٠" (Arabic numerals)
              toDate(new Date(), {format: "long"}) // Uses locale's predefined long format +
              + +
            diff --git a/docs/functions/toFraction.html b/docs/functions/toFraction.html index 4239814..1af00d1 100644 --- a/docs/functions/toFraction.html +++ b/docs/functions/toFraction.html @@ -9,4 +9,4 @@
            toFraction(0.5)                    // "1/2"
            toFraction(2.5) // "5/2"
            toFraction(2.5, {mixed: true}) // "2 1/2"
            toFraction(0.75, {pretty: true}) // "3⁄4"
            toFraction(0.333) // "333/1000"
            toFraction(-1.25, {mixed: true}) // "-1 1/4"
            -
            +
            diff --git a/docs/functions/toGrouped.html b/docs/functions/toGrouped.html index 1e4f9e1..bffcc49 100644 --- a/docs/functions/toGrouped.html +++ b/docs/functions/toGrouped.html @@ -9,4 +9,4 @@
            toGrouped(1000000) // "1,000,000"
            toGrouped(1234.56) // "1,234.56"
            toGrouped(1000000, {separator: '.'}) // "1.000.000" (European format)
            toGrouped(1000000, {separator: ' ', locale: 'ar'}) // "١ ٠٠٠ ٠٠٠"
            toGrouped(12345678, {segment: 4}) // "1234,5678" (custom grouping)
            toGrouped(12345678, {segment: [3, 2]}) // "1,23,45,678" (Indian numbering)
            -
            +
            diff --git a/docs/functions/toRelativeTime.html b/docs/functions/toRelativeTime.html index 7db12cc..e7b21bb 100644 --- a/docs/functions/toRelativeTime.html +++ b/docs/functions/toRelativeTime.html @@ -10,4 +10,4 @@
            // Assuming now is Jan 1, 2024, 12:00 PM
            toRelativeTime(new Date('2024-01-01T10:00')) // "2 hours ago"
            toRelativeTime(new Date('2024-01-03T12:00')) // "in 2 days"
            toRelativeTime(new Date('2024-01-01T11:58')) // "just now"

            // With level of detail = 2
            toRelativeTime(new Date('2023-12-30T10:00'), {lod: 2})
            // "2 days, 2 hours ago"

            // Abbreviated format
            toRelativeTime(new Date('2024-01-03T14:30'), {abbreviate: true})
            // "in 2d"

            // Without suffix
            toRelativeTime(new Date('2024-01-01T10:00'), {includeSuffix: false})
            // "2 hours"
            -
            +
            diff --git a/docs/functions/toRoman.html b/docs/functions/toRoman.html index b8b0242..920a03f 100644 --- a/docs/functions/toRoman.html +++ b/docs/functions/toRoman.html @@ -1 +1 @@ -toRoman | numerica
            numerica
              Preparing search index...

              Function toRoman

              • Parameters

                • n: number

                Returns string

              +toRoman | numerica
              numerica
                Preparing search index...

                Function toRoman

                • Parameters

                  • n: number

                  Returns string

                diff --git a/docs/functions/toWords.html b/docs/functions/toWords.html index e20c243..55660b7 100644 --- a/docs/functions/toWords.html +++ b/docs/functions/toWords.html @@ -8,4 +8,4 @@
                toWords(42)                          // "forty two"
                toWords(42, {hyphens: true}) // "forty-two"
                toWords(105, {and: true}) // "one hundred and five"
                toWords(1234) // "one thousand two hundred thirty four"
                toWords(1000000) // "one million"
                toWords(0) // "zero"
                toWords(3.14) // "three point one four"
                toWords(0.5) // "zero point five"
                -
                +
                diff --git a/docs/modules.html b/docs/modules.html index 10be197..93ab78f 100644 --- a/docs/modules.html +++ b/docs/modules.html @@ -1 +1 @@ -numerica
                numerica
                  Preparing search index...

                    numerica

                    Type Aliases

                    Locale
                    LocaleKey

                    Variables

                    locales

                    Functions

                    getLocale
                    setLocale
                    toAbbreviated
                    toBase
                    toFraction
                    toGrouped
                    toRelativeTime
                    toRoman
                    toWords
                    +numerica
                    numerica
                      Preparing search index...

                        numerica

                        Type Aliases

                        Locale
                        LocaleKey

                        Variables

                        locales

                        Functions

                        getLocale
                        setLocale
                        toAbbreviated
                        toBase
                        toDate
                        toFraction
                        toGrouped
                        toRelativeTime
                        toRoman
                        toWords
                        diff --git a/docs/types/Locale.html b/docs/types/Locale.html index 43c7f22..3761a43 100644 --- a/docs/types/Locale.html +++ b/docs/types/Locale.html @@ -1 +1 @@ -Locale | numerica
                        numerica
                          Preparing search index...

                          Type Alias Locale

                          Locale: typeof en_us
                          +Locale | numerica
                          numerica
                            Preparing search index...

                            Type Alias Locale

                            Locale: typeof en_us
                            diff --git a/docs/types/LocaleKey.html b/docs/types/LocaleKey.html index e1fbea4..b6e705c 100644 --- a/docs/types/LocaleKey.html +++ b/docs/types/LocaleKey.html @@ -1 +1 @@ -LocaleKey | numerica
                            numerica
                              Preparing search index...

                              Type Alias LocaleKey

                              LocaleKey: "en-us" | "en-US" | "en-gb" | "en-GB" | "de" | "ar"
                              +LocaleKey | numerica
                              numerica
                                Preparing search index...

                                Type Alias LocaleKey

                                LocaleKey: "en-us" | "en-US" | "en-gb" | "en-GB" | "de" | "ar"
                                diff --git a/docs/variables/locales.html b/docs/variables/locales.html index b8ffff2..5a7b81d 100644 --- a/docs/variables/locales.html +++ b/docs/variables/locales.html @@ -1 +1 @@ -locales | numerica
                                numerica
                                  Preparing search index...

                                  Variable localesConst

                                  locales: Record<NormalizedLocale, Locale> = ...
                                  +locales | numerica
                                  numerica
                                    Preparing search index...

                                    Variable localesConst

                                    locales: Record<NormalizedLocale, Locale> = ...
                                    diff --git a/src/to-words.ts b/src/to-words.ts index 0ecb608..2065729 100644 --- a/src/to-words.ts +++ b/src/to-words.ts @@ -56,6 +56,9 @@ export function toWords( if (n === 0) return 'zero' + const isNegative = n < 0 + n = Math.abs(n) + const parts: string[] = [] const [intStr, decStr] = n.toString().split('.') let intNum = Math.floor(Math.abs(Number(intStr))) @@ -101,7 +104,8 @@ export function toWords( } } - return parts.join(separator).replace(/\s+/g, ' ').trim() + const final = parts.join(separator).replace(/\s+/g, ' ').trim() + return isNegative ? "negative " + final : final } // Converts a 3-digit chunk into words diff --git a/tests/to-words.test.ts b/tests/to-words.test.ts index 22825a1..90ed05b 100644 --- a/tests/to-words.test.ts +++ b/tests/to-words.test.ts @@ -112,3 +112,58 @@ describe("toWords() — potential improvements", () => { expect(true).toBe(true) }) }) + +// Negative numbers +describe.each([ + [-1, {}, "negative one"], + [-9, {}, "negative nine"], + [-10, {}, "negative ten"], + [-11, {}, "negative eleven"], + [-15, {}, "negative fifteen"], + [-20, {}, "negative twenty"], + [-21, {}, "negative twenty one"], + [-99, {}, "negative ninety nine"], + [-100, {}, "negative one hundred"], + [-101, {}, "negative one hundred one"], + [-110, {}, "negative one hundred ten"], + [-115, {}, "negative one hundred fifteen"], + [-123, {}, "negative one hundred twenty three"], + [-999, {}, "negative nine hundred ninety nine"] +])("toWords() — negative integers", (n, options, expected) => { + it(`should convert ${n} to "${expected}"`, () => { + expect(toWords(n, options)).toBe(expected) + }) +}) + +// Negative numbers with 'and' +describe.each([ + [-101, { and: true }, "negative one hundred and one"], + [-120, { and: true }, "negative one hundred and twenty"], + [-999, { and: true }, "negative nine hundred and ninety nine"] +])("toWords() — negative integers with 'and'", (n, options, expected) => { + it(`should include 'and' correctly for ${n}`, () => { + expect(toWords(n, options)).toBe(expected) + }) +}) + +// Negative numbers with hyphens +describe.each([ + [-21, { hyphens: true }, "negative twenty-one"], + [-45, { hyphens: true }, "negative forty-five"], + [-99, { hyphens: true }, "negative ninety-nine"] +])("toWords() — negative integers with hyphens", (n, options, expected) => { + it(`should hyphenate correctly for ${n}`, () => { + expect(toWords(n, options)).toBe(expected) + }) +}) + +// Negative decimals +describe.each([ + [-3.14, {}, "negative three point one four"], + [-0.5, {}, "negative zero point five"], + [-12.34, { hyphens: true }, "negative twelve point three four"] +])("toWords() — negative decimal numbers", (n, options, expected) => { + it(`should correctly spell negative decimal ${n}`, () => { + expect(toWords(n, options)).toBe(expected) + }) +})