如何在正确的地方添加逗号和"and"

How to add commas and "and" at the right place

输入:秒,输出:语法正确的格式化时间(拼写单词)。

到目前为止,我设法从 400443731 year, 98 days, 5 hours, 37 minutes, 1 second - 注意正确的复数和逗号。

我缺少的是添加的 "and" 而不是最后一个逗号(当然只有在有足够的输入时)。例如 1 year and 1 second 用于输入 31556953 而不是我当前的 1 year, 1 second 在这种情况下。

function formatDuration (seconds) {

var numyears = Math.floor(seconds / 31556952);
if (numyears > 1) {var pluryears = " years, "} else {var pluryears = " year, "};
if (numyears > 0) {var printyears = numyears + pluryears;} else {var printyears = ''};

var numdays = Math.floor((seconds % 31556952) / 86400);
if (numdays > 1) {var plurdays = " days, "} else {var plurdays = " day, "};
if (numdays > 0) {var printdays = numdays + plurdays;} else {var printdays = ''};

var numhours = Math.floor(((seconds % 31556952) % 86400) / 3600);
if (numhours > 1) {var plurhours = " hours, "} else {var plurhours = " hour, "};
if (numhours > 0) {var printhours = numhours + plurhours;} else {var printhours = ''};

var numminutes = Math.floor((((seconds % 31556952) % 86400) % 3600) / 60);
if (numminutes > 1) {var plurminutes = " minutes, "} else {var plurminutes = " minute, "};
if (numminutes > 0) {var printminutes = numminutes + plurminutes;} else {var printminutes = ''};

var numseconds = (((seconds % 31556952) % 86400) % 3600) % 60;
if (numseconds > 1) {var plurseconds = " seconds"} else {var plurseconds = " second"};
if (numseconds > 0) {var printseconds = numseconds + plurseconds;} else {var printseconds = ''};

return(printyears + printdays + printhours + printminutes + printseconds)
}

formatDuration(31556953);

只是替换最后一个逗号的小正则表达式:

return (printyears + printdays + printhours + printminutes + printseconds)
    .replace(/, (.*)$/, " and ");

您只需在 return 中添加 'and'。

return(printyears + printdays + printhours + printminutes + 'and' + printseconds)

并去掉这一行'minute, '后面的逗号

if (numminutes > 1) {var plurminutes = " minutes "} else {var plurminutes = " minute "};

无关,但所提供的代码很难考虑。

我将复数位提取到它自己的方法中,大致是:

function pluralize(dur, s) {
  var ret = false;

  if (dur > 0) {
    ret = dur + ' ' + s;

    if (dur > 1) {
      ret += 's';
    }
  }

  return ret;
}

然后是主线代码,而不是手动执行所有操作,而是推送到一个数组上,例如,

function formatDuration(seconds) {
  var segments = [];

  var years  = Math.floor(seconds / 31556952)
    , sYears = pluralize(years, 'year')
    ;

  if (sYears) { 
    segments.push(sYears); 
  }

  // etc.

你只需要特例 seconds 值:

  var seconds = (((seconds % 31556952) % 86400) % 3600) % 60
    , sSeconds = pluralize(seconds, 'second')
    ;

  var tmp = segments.join(', ');
  if (!sSeconds) {
    return tmp;
  }

  return tmp + ' and ' + sSeconds;
}

这可以进一步清理,但会产生如下输出:

1 year, 2 hours, 46 minutes and 43 seconds
1 year and 3 seconds

(虽然我更喜欢牛津逗号。)

我仍然会做的事情:

  • 停止重新计算一切;记录剩余的秒数。
  • 将数组传递到函数中,避免在主线代码中进行手工劳动。
    • (或以其他方式结束。)

https://gist.github.com/davelnewton/a1371867527c5f1530498e1555e2fb0a

更紧凑的解决方案,按预期输出时间字符串:

function formatDuration (seconds) {
  var values = {
    years: Math.floor(seconds / 31556952),
    days: Math.floor((seconds % 31556952) / 86400),
    hours: Math.floor(((seconds % 31556952) % 86400) / 3600),
    minutes: Math.floor((((seconds % 31556952) % 86400) % 3600) / 60),
    seconds: (((seconds % 31556952) % 86400) % 3600) % 60,
  };
  var withUnits = Object.keys(values)
  .filter(function(unit) { return values[unit] > 0; })
  .map(function (unit) {
    var value = values[unit];
    return value + ' ' + (value === 1 ? unit.slice(0, -1) : unit);
  });
  return (withUnits.length > 1 ? withUnits.slice(0, -1).join(', ') + ' and ' : '') + withUnits.pop();
}

console.log(formatDuration(40044373));

我正是为此目的编写了一个小型库:

https://github.com/adamshaylor/compound-subject

在你的情况下,你会像这样使用它:

var formattedTimeString = compoundSubject([
    numyears + 'years',
    numdays + 'days',
    numhours + 'hours',
    numminutes + 'minutes',
    numseconds + 'seconds'
]).make();

产生类似的东西:

2 years, 5 days, 3 hours, 10 minutes and 2 seconds

您还可以通过调用 delimitAll() 添加牛津逗号。