Git Product home page Git Product logo

parse-duration's Introduction

parse-duration Build Status

convert a human readable duration to ms

Installation

NPM

then in your app:

import parse from 'parse-duration'

or CommonJS:

var parse = require('parse-duration')

API

parse(str, format='ms')

Convert str to ms

var ns = parse('1ns') // => 1 / 1e6
var μs = parse('1μs') // => 1 / 1000
var ms = parse('1ms') // => 1
var s = parse('1s')   // => ms * 1000
var m = parse('1m')   // => s * 60
var h = parse('1h')   // => m * 60
var d = parse('1d')   // => h * 24
var w = parse('1w')   // => d * 7
var y = parse('1y')   // => d * 365.25

It can also handle basic compound expressions

parse('1hr 20mins') // => 1 * h + 20 * m
parse('1 hr 20 mins') // => 1 * h + 20 * m

youtube format

parse('1h20m0s') // => 1 * h + 20 * m

comma seperated numbers

parse('27,681 ns') // => 27681 * ns

And most other types of noise

parse('running length: 1hour:20mins') // => 1 * h + 20 * m

You can even use negatives

parse('2hr -40mins') // => 1 * h + 20 * m

And exponents

parse('2e3s') // => 2000 * s

Available unit types are:

  • nanoseconds (ns)
  • microseconds (μs)
  • milliseconds (ms)
  • seconds (s, sec)
  • minutes (m, min)
  • hours (h, hr)
  • days (d)
  • weeks (w, wk)
  • months
  • years (y, yr)

And its easy to add more, including unicode:

parse['сек'] = parse['sec']
parse('5сек') // => 5000

The output format can also be defined

parse('1hr 20mins', 'm') // => 80

parse-duration's People

Contributors

achingbrain avatar alonesuperman avatar daerogami avatar dy avatar jkroso avatar nitive avatar nordluf avatar piotr-musialek-skyrise avatar remcohaszing avatar sawa-ko avatar sparshithnr avatar trim21 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

parse-duration's Issues

Cannot parse with multiply or division

When I try to parse something like 1000*60 (multiply)

parse("1000*60");

Instead of returning 60000(which is 1 min), it returns 1060

It also happened when trying to parse something like 10000/10 (division)

parse("10000/10");

Instead of returning 1000(which is 1 sec), it returns 10010

Support singular form without integer

Now I can use multiple ways to get number of milliseconds for singular forms of string:

parse('1h') // 3600000
parse('1 h') // 3600000
parse('1hour') // 3600000
parse('1 hour') // 3600000
parse('1hours') // 3600000
parse('1 hours') // 3600000
// ...

But I can't do in the following way without integer:

parse('h') // 0, should be 3600000
parse('hour') // 0, should be 3600000

Support multiple duration formats, other than human readable

There is a couple wishes in issues to support dotnet TimeSpan and ISO8061 duration formats #29, #30:

  • [-][d.]hh:mm:ss[.fffffff]
  • [-][d:]h:mm:ss[.FFFFFFF]
  • [-]d:hh:mm:ss.fffffff
  • P[YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]
  • PYYYYMMDDThhmmss
  • PnYnMnDTnHnMnS
  • PnW

👍🏼 Supporting them would simplify life for generic parse-duration user: migrating data, reduce API friction (audio, video) etc.
👍🏼 That would be the most compact generic-case solution.
👎🏼 Mixing concerns: now we focus on human readable durations, eg. entered by user in UI/CLI/docs/APIs. Inflating package to all cases can become costly.
👎🏼 Maintenance burden: once somebody submits new duration format, we gotta update the package.
👎🏼 It complicates implementation, inflates size somewhat, also some performance loss - price that paid by every current user.

Could not find a declaration file for module 'parse-duration'

Full error:

Could not find a declaration file for module 'parse-duration'. '/home/rajas/folder-size-checker/node_modules/.pnpm/[email protected]/node_modules/parse-duration/index.mjs' implicitly has an 'any' type.
  Try `npm i --save-dev @types/parse-duration` if it exists or add a new declaration (.d.ts) file containing `declare module 'parse-duration';`ts(7016)

Possible causes:

  • .d.ts file is not being resolved as typings for the .mjs file
  • package.json doesn't correctly include types

Support for local decimal separator

How can I set what is treated as a decimal separator? I can easily add support for units in more languages, but half of the world uses comma as a decimal separator and I can't seem to find a way to switch it.

Right now:
parse('1.500 seconds') - resulting in one and a half second
parse('1,500 seconds') - resulting in one and a half thousand seconds

I need:
parse('1,500 seconds') - resulting in one and a half second

I understand that it's impossible to parse it both ways, but at least what we could have is a way to override the decimal separator based on our language we use in our apps. Maybe similar to how we add language specific units?
parse['decimalSeparator'] = ',';

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main resolved in ${path}/node_modules/parse-duration/package.json

Hi.
Thanks for parse-duration, I've been using it in loads of my libraries, however it's started failing under Node 14. I'm probably missing something obvious, getting the following error...

$ node --version
v14.2.0
$ node
Welcome to Node.js v14.2.0.
Type ".help" for more information.
> const parse = require('parse-duration');
Uncaught:
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main resolved in /Users/steve/Development/cressie176/pipsqueak/node_modules/parse-duration/package.json
    at resolveExportsTarget (internal/modules/cjs/loader.js:596:11)
    at applyExports (internal/modules/cjs/loader.js:454:14)
    at resolveExports (internal/modules/cjs/loader.js:507:23)
    at Function.Module._findPath (internal/modules/cjs/loader.js:635:31)
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1007:27)
    at Function.Module._load (internal/modules/cjs/loader.js:890:27)
    at Module.require (internal/modules/cjs/loader.js:1080:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at repl:1:15
    at Script.runInThisContext (vm.js:131:20) {
  code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}

Any ideas?

Integrate into compute-incrdatespace

Here is awesome package using the same functionality: https://github.com/compute-io/incrdatespace

I think it would be winning for both to cross-test cases and make integration.

The cases:

  • ms, millisecond, milliseconds
  • s, sec, secs, second, seconds
  • m, min, mins, minute, minutes
  • h, hr, hrs, hour, hours
  • d, day, days
  • w, wk, wks, week, weeks
  • b, month, months
  • y, yr, yrs, year, years

Anyways there is no tests, so mb worth adding.
Just for note.

cc @kgryte is there any sense in that?

Two minor but rather non-expected cases of behaviour

Dear Jake

Thanks for your code. I would like to inform you on two cases I recently encountered:

let n = parse(1)

index.js:62 str = str.replace(/(\d),(\d)/g, '$1$2') ^ TypeError: str.replace is not a function

let n = parse('1')   // => null

In both cases I would rather expect a returned value of 1.

Regards
H. R. Baer

index.d.ts is not in the package

How to recreate the issue:

  1. npm install parse-duration
  2. open parse-duration in node_modules and see that "index.d.ts" is not a part of the package

Thanks

Add module.exports.default or refactor d.ts file

As we known, the dist file was commonjs styled, but d.ts use ESM to describe it.

my tsconfig

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "strict": true,
    "noImplicitAny": true,
    "incremental": true,
    "resolveJsonModule": true,
    "types": [
      "node",
      "jest"
    ],
    "lib": [
      "ESNext",
      "ScriptHost",
    ]
  },
  "exclude": ["node_modules", "dist"]
}

source code in .ts file

import parse from "parse-duration";

parse("30 mins");

target (compiled by tsc) in .js file

const parse_duration_1 = tslib_1.__importDefault(require("parse-duration"));
parse_duration_1.default("30 mins");

Above code should have runtime error certainly

So we have to use esModuleInterop (maybe some other option needed?)

My Suggestion1 (Not Recommand)

Is it necessary? I think if u can modify the d.ts file

export default function parse (str: string, format?: Units): number | null

to below code, we can drop esModuleInterop option

// ...Units defintion
declare function parse (str: string, format?: Units): number | null
export = parse

then we can easily use import parse = require("parse-duration")

My suggestion2 (Recommand)

forget suggestion1 then just simple add module.exports.default = parse in your index.js

types flexibility

the current type system is not as flexible as parsing.

doing

var parseDuration = require("[email protected]")

console.log(parseDuration('10 seconds', 'seconds'))

will print NaN
but doing

var parseDuration = require("[email protected]")

console.log(parseDuration('10 seconds', 's'))

will print 10, the correct answer.

I believe that the unit types should be as flexible as the parsing types as not having it that way can lead to errors and weirdness.

Unit validation

Wonderful module, very useful.
We should have unit validation also. Like parse('I have 2 mangoes and 5 apples') should return null.

Inaccurate d.ts file

Hi,

According to the d.ts the parse function return a number but actually parse(1) or parse(undefined) returns null
so
export default function parse (str: string): number
should be
export default function parse (str: string): number || null

thanks
Lior

Not a function exception

Import with
import parse from "parse-duration";
or
import {parse} from "parse-duration";

use it:
parse("10s")

you will get
"parse_duration_1.default is not a function"

Can you please provide a type script example of how to use parse-duration?

Thanks,
Lior

TypeScript definition

According to https://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-function-d-ts.html, this is as simple as

// ./index.d.ts

export = parse

/**
 * convert `str` to ms
 */
function parse (str: string): number

And, add "typings": "index.d.ts", in your package.json. Then, upload to NPM.

Might create a Pull Request later. Hope this package will be actively maintained.

Anyways, for anyone reading this, you can also create declaration.d.ts with

declare module 'parse-duration' {
  export = parse

  /**
   * convert `str` to ms
   */
  function parse (str: string): number
}

Typescript support for adding more units

Unfortunately current type definition is only for the function. There is no way to add more units cause there is no index signature defined and parse['anything'] = generates error.

.d.ts file should have something like this instead:

declare const parse: ((input: string, format?: Units) => number) & {
  [key: string]: number | null;
};

export default parse;

I used the above to overwrite the type and it works fine for me.

[feature request] support more units which not in English

Hi, jkroso

Although we can use parse.newUnit to extend more unit, your regexp may limit the unit as [a-zµμ]

I suggest it could change to some else such as [^\d\s] to make more possibility

The change is just example, It fail to pass test case because of the noisy word

So a safer way could be either of follow:

  • Check the last capture group

    1. Give the parse object a method called registerUnit, it will push all unit into an array
    2. The last capture group (unit) will check if it contains any unit
  • Dynamically create regular expressions by current units collection array

If u agree, I can do some job(by the way, improve the .d.ts file to allow us extend units under typescript) and take a pr in several days

Can't build react project

I use parse-duration package inside react project.

When I execute yarn build I see this error:

parse-duration/index.mjs: symbol.charCodeAt is not a function at Array.map (<anonymous>)

I tried with version 1.0.2 and with 1.0.0

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.