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");
Achintha Samindika
quelle
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.

jtromans
quelle
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");
janhartmann
quelle
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.

Volune
quelle
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);
            }
Aida Nowzari
quelle
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});
Erik Martín Jordán
quelle
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! :) :)

Josef Held - Satanko
quelle
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
Bello Hargbola
quelle