1

I'm working on a project where the user needs to provide time estimates on specific tasks. Im wondering if there's a script already out there ( like date.js ) that can take user input and parse it to number of seconds.

Examples: 
"2 days" = 172800
"2 hours" = 7200
"1d 5h" = 104400
"15 minutes" = 900

date.js is great for finding the specific date in the future, but I need the total number of seconds, not a specific end date.

I will code this myself if it doesn't already exist, just want to save some time if it's out there.

3 Answers 3

3

Here's a library off the top of my head (sorry I couldn't resist)

var stringToSeconds = (function() {
  //Closure to define things that
  //do not change per function call

  var reg = /(\d+)\s*(\w+)/g;
  var units = {};

  //Lets be verbose
  units.seconds = 1;
  units.minutes = units.seconds * 60;
  units.hours = units.minutes * 60;
  units.days = units.hours * 24;
  units.weeks = units.days * 7;
  units.months = units.weeks * 4;
  units.years = units.months * 12;

  //Match unit shorthand
  var getUnit = function(unit) {
    unit = unit.toLowerCase();
    for (var name in units) {
      if (!units.hasOwnProperty(name)) continue;

      if (unit == name.substr(0, unit.length)) return units[name];
    }
    return 0;
  };


  return function(str) {
    var match, totalSeconds = 0;

    while (match = reg.exec(str)) {
      var num = match[1], unit = match[2];

      totalSeconds += getUnit(unit) * num;
    }

    return totalSeconds;
  }
}());

Try it out: http://jsbin.com/ozeda/2/edit

Sign up to request clarification or add additional context in comments.

4 Comments

Very nice :) Works like a charm.
It's rather difficult to convert from a number of seconds/minutes/hours/days/weeks into a number of months/years, because the number of days per month or per year is irregular and varies month-to-month and year-to-year.
Ya, i'm thinking about taking months and years out of the script when I put it into production. Not needed in my case.
@Justice Yea I realized that but thought to put it in anyway for examples sake. Thinking about it again though, I might prefer to use the new Date constructor to build a future timestamp then subtract the current timestamp from it.
0

Made a change to the unit values, the calculation for months was messing up the years.

units.seconds = 1;
units.minutes = 60;
units.hours = 3600;
units.days = 86400;
units.weeks = 604800;
units.months = 262974383;
units.years = 31556926;

Comments

0

Here is my final working version, based off of MooGoo's excellent script. Ill update this after some more bug/browser testing.

Please let me know if you have any improvements :)

  • added support for decimals. 1.5 hours = 1 hour 30 minutes
  • added get_string function. Pass in number of seconds and get a formatted string.
  • made it so the number defaults to hours. 5 = 5 hours

Demo: http://jsbin.com/ihuco3/2/edit

var string2seconds = {

  reg: /([\d]+[\.]?[\d{1,2}]?)\s*(\w+)/g,

  units: function()
  {
    var units = {};
    units.seconds = 1;
    units.minutes = 60;
    units.hours = 3600;
    units.days = 86400;
    units.weeks = 604800;
    units.months = 262974383;
    units.years = 31556926;
    return units;
  },

  get_unit: function(unit)
  {
    var units = this.units();

    unit = unit.toLowerCase();

    for (var name in units)
    {
      if( !units.hasOwnProperty(name) ) continue;
      if( unit == name.substr(0, unit.length) ) return units[name];
    }

    return 0;
  },

  get_string: function( seconds )
  {
    var years = Math.floor(seconds/31556926);
    var days = Math.floor((seconds % 31556926)/86400);
    var hours = Math.floor(((seconds % 31556926) % 86400) / 3600);
    var minutes = Math.floor((((seconds % 31556926) % 86400) % 3600 ) / 60);
    var string = '';

    if( years != 0 ) string = string + years + ' year'+this.s(years)+' ';
    if( days != 0 ) string = string + days + ' day'+this.s(days)+ ' ';
    if( hours != 0 ) string = string +  hours + ' hour'+this.s(hours)+ ' ';
    if( minutes != 0 ) string = string + minutes + ' minute'+this.s(minutes)+ ' ';

    if( string == '' ) return false;

    return string;
  },

  get_seconds: function( str )
  {
    var match, totalSeconds = 0, num, unit;

    if( (str - 0) == str && str.length > 0 )
    {
      str = str + 'hours';
    }

    while (match = this.reg.exec(str))
    {
      num = match[1];
      unit = match[2];
      totalSeconds += this.get_unit(unit) * num;
    }

    return totalSeconds;
  },

  s: function( count )
  {
    if( count != 1 ) return 's';
    return '';
  }

};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.