【问题标题】:Round moment.js object time to nearest 30 minute interval将 moment.js 对象时间舍入到最近的 30 分钟间隔
【发布时间】:2014-10-09 00:51:45
【问题描述】:

我试图将 moment.js 时间对象舍入到下一个最近的 30 分钟间隔。但看起来我的逻辑我们错了。

例如:

10:13am -> 10:30am
11:45am -> 12:00pm

这是我当前的代码

start = moment();
minuteReminder = start.minute() % 30;
start.add(minuteReminder, 'minutes');
start.format("D YYYY, h:mm:ss a");

【问题讨论】:

  • 只有4个条件,你可以切换大小写。
  • 您正在寻找余数,而不是差异。根据我的解决方案,您需要同时执行这两项操作。
  • This 对我有用,这是一个非常好的解决方案。

标签: javascript momentjs


【解决方案1】:

2021 年编辑:easiest solution

const start = moment('2018-12-08 09:42');
const remainder = 30 - (start.minute() % 30);
 
const dateTime = moment(start).add(remainder, "minutes").format("DD.MM.YYYY, h:mm:ss a");

console.log(dateTime);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>

百万种方法可以做到这一点。你真的不需要 moment.js。无论如何,这是一个。

【讨论】:

  • 我觉得你搞错了,``` 余数 = (moment().minute()%30)-30```
  • 我觉得应该是code 30 - (start.minute() % 30)
  • 发现此问题的人可能希望包含 .startOf('minute') 以重置内在日期对象的秒数和毫秒数。
  • 这似乎不符合要求。甚至样本 sn-p 也不会将 09:42 舍入到 最近 30 分钟间隔;它将它舍入到 next 30 分钟间隔。结果应该是 09:30,而不是 10:00。
  • OP 在其原始问题中提供了许多示例,这解决了这些示例。帖子的标题不明确。
【解决方案2】:

基于@Volune 和@Cabloo 的答案和cmets,更新版本可能如下所示:

function round(date, duration, method) {
    return moment(Math[method]((+date) / (+duration)) * (+duration)); 
}

然后可以像这样使用:

var date = moment();
var roundedDate = round(date, moment.duration(15, "minutes"), "ceil");

【讨论】:

  • 实现扩展功能的绝妙方法!
  • 恢复原始时区可能有意义,否则此信息会丢失。 F.e.通过将 .tz(date.tz()) 添加到末尾。
【解决方案3】:

通用解决方案:

var ROUNDING = 30 * 60 * 1000; /*ms*/
start = moment();
start = moment(Math.ceil((+start) / ROUNDING) * ROUNDING);
start.format("D YYYY, h:mm:ss a");

您可以将 ROUNDING 从 30 分钟更改为您想要的任何值,如果您想要另一种舍入值的方式,可以将 Math.ceil 更改为 Math.round 或 Math.floor。

【讨论】:

  • 我喜欢这个。您可以将 ROUNDING 变量转换为 moment.duration(...),即 function date_round(date, duration) { return moment(Math.floor((+date)/(+duration)) * (+duration)); } 像这样使用 date_round(moment(), moment.duration(30, 'minutes'))
【解决方案4】:

你可以通过一个简单的 if-else 子句来做到这一点:

if(moment().minute()> 30){
    var myTime = moment().minute(30).second(0);
} else {
    var myTime = moment().minute(0).second(0);
}

【讨论】:

  • 虽然在问题标题中使用了round这个词,OP希望有类似于ceil的东西。您的解决方案两者都不提供,而是提供floor 的效果。
【解决方案5】:

你可以用两个 if 来做到这一点:

// Current date
let now = moment();

// Getting hour and minute
let hour   = now.hour();
let minute = now.minute();

// Rounding minute on 30 mins interval
if(minute <= 30) now.set({minute: 30});
if(minute >  30) now.set({hour: hour + 1, minute: 0});

【讨论】:

    【解决方案6】:

    即使问题已得到解答,我也想分享我的解决方案。

    var moment = require('moment');
    
    const roundToNearestXXMinutes = (start, roundTo) => {
        let remainder = roundTo - (start.minute()+ start.second()/60) % roundTo;
    
        remainder = (remainder >  roundTo/2) ? remainder = -roundTo + remainder : remainder;
        const changedDate = moment(start).add(remainder, "minutes" ).seconds(0).format("DD.MM.YYYY HH:mm:ss");    
    }
    
    roundToNearestXXMinutes(moment(), 15);
    

    编辑:感谢 Ishmael Sibisi 指出我的代码中的一个缺陷! :)

    【讨论】:

      【解决方案7】:

      就我而言,我想要类似的东西

      04-28-2021 20:00 => 04-28-2021 20:00
      04-28-2021 20:30 => 04-28-2021 20:30
      04-28-2021 20:11 => 04-28-2021 20:00
      04-28-2021 20:35 => 04-28-2021 20:30
      

      所以下面的函数成功了

      function toNearest30Minutes(date) {
        const start = moment(date)
        let remainder: number
        const elapse = start.minute() % 30
        if (elapse === 0) {
          return moment(date).format()
        } else {
          remainder = 30 - elapse
          return moment(start).add(remainder, "minutes").format()
        }
      }
      

      上面的函数只是上面@jtromans answer的改编

      【讨论】:

        【解决方案8】:

        一线解决方案

         moment().add( moment().minute() > 30 && 1 , 'hours').minutes( moment().minute() <= 30 ? 30 : 0).format("hh:mm a")
        

        工作示例:

        var min = moment().minute()
        var dateTime = moment().add(min > 30 && 1 , 'hours').minutes(min <= 30 ? 30 : 0).format("hh:mm a")
        
        console.log(dateTime);
        &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"&gt;&lt;/script&gt;

        【讨论】:

          【解决方案9】:

          下面的代码将当前时间四舍五入到最接近的 30 分钟,并且还完美地处理了任何尾随 秒

              var moment = require('moment')
              var main = Date.now() //2020-03-13T23:17:34+01:00
              var mainFormat = moment(main)
              var secs = mainFormat.second()
              var justMinutes = mainFormat.subtract(secs, 'seconds')
              var remainder = 30 - (justMinutes.minute() % 30);
              var dateTime = moment(justMinutes).add(remainder, 'minutes')
              var final = dateTime.format()
              console.log(final) 
              //2020-03-13T23:20:00+01:00
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-03-24
            • 1970-01-01
            • 2021-11-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-12-02
            相关资源
            最近更新 更多