繁体   English   中英

Javascript:将天数转换为年、月和日

[英]Javascript: convert number of days to years, months and days

我有几天、几个月和几年。 我正在他们之间进行计算。 这意味着我必须将 2 年 3 个月零 10 天除以 1/4。 现在我有以下代码:

const getCurrentDate = moment().format("YYYY-MM-DD");
const timeEnd = moment(moment(DefEndDate).format("YYYY-MM-DD"));
const diff = timeEnd.diff(getCurrentDate);
const diffDuration = moment.duration(diff);
const diffCount = moment.duration(diff).asDays();
console.log(diffCount);
console.log("Years:", diffDuration.years());
console.log("Month:", diffDuration.months());
console.log("Days:", diffDuration.days());

const diffCount = moment.duration(diff).asDays(); //Get it as days
const [unserve, setUnserve] = useState(''); //set value to variable
    const res = unserve.split('/'); //split 1/4 to 1.4
    const x = parseFloat(res[0] + "." + res[1]); //convert it to float
    var quotient = Math.floor(diffCount/x); //calculate
    console.log(quotient);
    //returned 832 / 1.4 = 594 days

现在我需要将输出数(天)返回到年、月和日。 我不能那样做。 如何转换? 另一个问题是,这种方式可以成为最佳解决方案吗?

我无法决定您真正想要做的是将日期范围划分为具有相等天数的固定数量的时间段,还是从一个日期开始,以年、月和日为单位添加一个时间段以获得结束日期,然后将其分成相等的时期。

以下假设为后者。

我必须将 2 年 3 个月零 10 天除以 1/4

该时间段涵盖的天数取决于它的起止日期,因此您必须从该范围的开始和结束日期开始。

在您的代码中:

const getCurrentDate = moment().format("YYYY-MM-DD");

getCurrentDate设置为类似 2020-02-11 的字符串。

const timeEnd = moment(moment(DefEndDate).format("YYYY-MM-DD"));

getCurrentDate的字符串值创建一个 moment 对象,并将timeEnd设置为另一个字符串。

const diff = timeEnd.diff(getCurrentDate);

这会尝试调用timeEnddiff方法,它是一个字符串。 字符串没有diff方法,因此表达式返回 undefined,尝试调用它会抛出类似TypeError: '2020-02-11'.diff is not a function

您的其余代码似乎基于算法

如果您有以年、月、日等为单位的预定时间段,您可以从开始日期开始,添加时间段,然后得到天数差异。 将该差异除以您想要的期间数,然后按顺序相加以获得各种结束日期。

以下示例使用 moment.js,因为这就是您似乎正在使用的内容,但是没有库的版本大致相同。 它返回一组日期,从开始日期开始,因此日期比句点多。

 function getDates( start = new Date(), years = 0, months = 0, days = 0, parts = 1) { // Get start and end as moment objects let m = moment(start).startOf('day'); let end = moment(m); end.add({years:years, months:months, days:days}); // Get days difference and number of days to add for each period let daysDiff = end.diff(m, 'days'); let f = daysDiff / parts; let dayArray = [m.format('YYYY-MM-DD')]; let i = 0; while ((f * ++i) <= daysDiff) { let d = moment(m).add(f * i, 'days') dayArray.push(d.format('YYYY-MM-DD')); } return dayArray; } // Get dates for 4 even periods over 2 years, 3 months and // 10 days from today console.log(getDates(new Date(), 2, 3, 10, 4));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

由于子周期长度几乎总是不是偶数天数(在上述情况下大约为 207.5),我允许格式化以有效地截断一天的小数部分。 您可能希望使用其他一些舍入算法来更均匀地分布余数。

另一方面,如果您有开始日期和结束日期并且想要相同数量的时间段,则以下内容要简单得多(并且不使用库):

 // Helpers - use UTC do avoid DST issues function toUTCDate(s) { let b = s.split(/\\D/); return new Date(Date.UTC(b[0], --b[1], b[2])); } function formatUTC(date) { return date.toISOString().substr(0, 10); } /* @param {string} start - date string in format 'YYYY-MM-DD' ** @param {string} end - date string in format 'YYYY-MM-DD' ** @param (numbe} n - number of required periods ** @returns {Array} array of date strings in format 'YYYY-MM-DD' */ function periods(start, end, n) { let s = toUTCDate(start); let e = toUTCDate(end); let diff = e - s; let f = diff / n; let result = [formatUTC(s)]; // Allow for rounding of decimal f in comparison while (e - s > n) { s.setTime(s.getTime() + f); result.push(formatUTC(s)) } return result; } console.log(periods('2020-02-09','2022-05-19', 4));

这两种方法产生的结果略有不同,您需要弄清楚这是否重要。

很久以前,我使用这样的代码将秒转换为小时、分钟和秒:

var hours = Math.floor(sec / 3600);
var minutes = Math.floor((sec - hours * 3600) / 60);
var seconds = Math.round(sec - hours * 3600 - minutes * 60);

天、月、年的数学应该有点相似,但我生锈的大脑不想去想它

UPD

此功能似乎可以满足您的需求

const daysFmt = days => {
  const years = Math.floor(days / 365);
  const months = Math.floor((days - years * 365) / 30);
  const d = Math.round(days - years * 365 - months * 30);

  let res = [];
  if (years > 0) {
    res.push(years + ' y');
  }
  if (months > 0) {
    res.push(months + ' m');
  }
  if (d > 0) {
    res.push(d + ' d');
  }

  return res.join(', ');
}

但是这个解决方案有一个细微差别:它假设月份 = 30 天。 您可能想要添加if语句以在输入为31返回 '​​1 m' 或者如果输入小于 32 则仅返回天数。 测试结果:

daysFmt(31);
"1 m, 1 d"
daysFmt(180);
"6 m"
daysFmt(185);
"6 m, 5 d"
daysFmt(356);
"11 m, 26 d"
daysFmt(365);
"1 y"
daysFmt(420);
"1 y, 1 m, 25 d"
daysFmt(3650);
"10 y"
daysFmt(3685);
"10 y, 1 m, 5 d"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM