Runde moment.js Objektzeit auf das nächste 30-Minuten-Intervall


72

Ich habe versucht, das Zeitobjekt von moment.j auf das nächste 30-Minuten-Intervall abzurunden. Aber sieht meine Logik uns falsch aus.

Ex:

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

Hier ist mein aktueller Code

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

Es gibt nur 4 Bedingungen, Sie können sie umschalten.
— Junle Li

1
Sie finden den Rest, nicht den Unterschied. Sie müssen beides gemäß meiner Lösung tun.
— Jtromans

Das funktioniert bei mir, es ist wirklich eine gute Lösung.
— Sandeep.gosavi

Antworten:


120

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>

Millionen Möglichkeiten, dies zu tun. Du brauchst moment.js nicht wirklich. Wie auch immer, hier ist einer.


Ich denke, Sie machen einen Fehler, `` `rest = (moment (). Minute ()% 30) -30```
— 32teeths

5
Ich denke, es sollte code30 sein - (start.minute ()% 30)
— artem_p

Personen, die dies finden, möchten möglicherweise einschließen .startOf('minute'), um Sekunden und Millisekunden des intrinsischen Datumsobjekts zurückzusetzen.
— Adrian Föder

2
Dies scheint nicht das zu tun, wonach gefragt wurde. Selbst das Sample-Snippet rundet 09:42 nicht auf das nächste 30-Minuten-Intervall ab. es rundet es auf das nächste 30-Minuten-Intervall. Das Ergebnis sollte 09:30 und nicht 10:00 sein.
— Thor84no

1
Das OP hat in seiner ursprünglichen Frage eine Reihe von Beispielen angegeben, die diese Beispiele ansprechen. Der Titel des Beitrags ist nicht eindeutig.
— Jtromans

59

Basierend auf den Antworten und Kommentaren von @Volune und @Cabloo kann eine aktualisierte Version folgendermaßen aussehen:

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

Welches kann dann verwendet werden wie:

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

1
Geniale Möglichkeit, erweiterte Funktionen zu ermöglichen!
— Ancinek

2
Wahrscheinlich ist es sinnvoll, die ursprüngliche Zeitzone wiederherzustellen, da sonst diese Informationen verloren gehen. Fe durch Hinzufügen von .tz (date.tz ()) am Ende.
— XZen

35

Eine generische Lösung:

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

Sie können ROUNDINGvon 30 Minuten auf das ändern , was Sie möchten, und Math.ceilnach Math.roundoder, Math.floorwenn Sie eine andere Möglichkeit zum Runden des Werts wünschen.


8
Ich mag diesen. Sie könnten die ROUNDING-Variable in eine moment.duration (...) konvertieren, dh function date_round(date, duration) { return moment(Math.floor((+date)/(+duration)) * (+duration)); } wie folgt verwendetdate_round(moment(), moment.duration(30, 'minutes'))
— Zane

4

Sie können dies mit einer einfachen if-else-Klausel tun:

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

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

1
Obwohl das Wort roundim Fragentitel verwendet wurde, möchte OP etwas Ähnliches haben ceil. Ihre Lösung bietet keine, sondern eine Wirkung von floor.
— Fr0zenFyr

3

Sie könnten es mit zwei Wenns tun:

// 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});

1

Obwohl die Frage beantwortet wurde, möchte ich auch meine Lösung teilen.

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);

EDIT: Danke an Ishmael Sibisi für den Hinweis auf einen Fehler in meinem Code! :) :)


0

Der folgende Code rundet die aktuelle Zeit auf die nächsten 30 Minuten auf und kümmert sich auch fehlerfrei um alle nachfolgenden Sekunden

    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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.