Multiplizieren Sie TimeSpan in .NET

86

Wie multipliziere ich ein TimeSpan-Objekt in C #? Angenommen, die Variable durationist eine Zeitspanne , möchte ich zum Beispiel

duration*5

Aber das gibt mir einen Fehler "Operator * kann nicht auf die Typen TimeSpan und int angewendet werden". Hier ist meine aktuelle Problemumgehung

duration+duration+duration+duration+duration

Dies erstreckt sich jedoch nicht auf nicht ganzzahlige Vielfache, z. duration * 3.5

Oberst Panik
quelle
5
Dies ist eine sehr offensichtliche Anforderung und einfach zu implementieren. Ich frage mich, warum MS nicht daran gedacht hat, Multiplikation und Division als Standardoperatoren einzuschließen.
Andy

Antworten:

103

Aus diesem Artikel

TimeSpan duration = TimeSpan.FromMinutes(1);
duration = TimeSpan.FromTicks(duration.Ticks * 12);
Console.WriteLine(duration);     
Justin Pihony
quelle
4
Danke, den ich benutzt habeTimeSpan.FromTicks((long)(duration.Ticks*multiplier))
Colonel Panic
2
Ich würde lieber Erweiterungsmethoden verwenden. Wie von Stephen Hewlett in seinen Antworten auf diese Frage vorgeschlagen.
Mike de Klerk
11
@ MikedeKlerk Einverstanden, aber das ist mehr syntaktischer Zucker. Das OP muss noch die Wurzel der Antwort kennen, damit sie in jeder Methode, Erweiterung oder nicht angewendet werden kann
Justin Pihony
2
Vielen Dank für das Kompliment, aber ich fühle mich verpflichtet darauf hinzuweisen, dass @JustinPihony fast zwei Jahre zuvor geantwortet hat und es die Informationen in seiner Antwort waren, die es mir ermöglichten, meine zu schreiben.
Stephen Hewlett
45

Für diejenigen, die kopieren und einfügen möchten:

namespace Utility
{
    public static class TimeSpanExtension
    {
        /// <summary>
        /// Multiplies a timespan by an integer value
        /// </summary>
        public static TimeSpan Multiply(this TimeSpan multiplicand, int multiplier)
        {
            return TimeSpan.FromTicks(multiplicand.Ticks * multiplier);
        }

        /// <summary>
        /// Multiplies a timespan by a double value
        /// </summary>
        public static TimeSpan Multiply(this TimeSpan multiplicand, double multiplier)
        {
            return TimeSpan.FromTicks((long)(multiplicand.Ticks * multiplier));
        }
    }
}

Anwendungsbeispiel:

using Utility;

private static void Example()
{
    TimeSpan t = TimeSpan.FromSeconds(30).Multiply(5);
}

t wird als 150 Sekunden enden.

Stephen Hewlett
quelle
Erweiterungsmethoden sind die bequemste Lösung für diese Art von Problemen.
Mike de Klerk
Der Multiplikatorparameter kann ohne zusätzliche Kosten einen Typ lang haben.
tm1
13

Die TimeSpanStruktur stellt keine Überlastung für den *Bediener bereit , daher müssen Sie dies selbst tun:

var result = TimeSpan.FromTicks(duration.Ticks * 5);
Kent Boogaart
quelle
5

Sie können die internen Daten von TimeSpan verwenden, nämlich Ticks.

TimeSpan day = TimeSpan.FromDays(1);
TimeSpan week = TimeSpan.FromTicks(day.Ticks * 7);
Kendall Frey
quelle
3

Multiplizieren ist jetzt für TimeSpan verfügbar !!!

Aber nur für .NET Core und .NET Standard .

Seit .NET Core 2.0 (oder .NET Standard 2.1 ) können Sie den folgenden Code erfolgreich ausführen:

Console.WriteLine(TimeSpan.FromSeconds(45) * 3);
// Prints:
// 00:02:15

Einschränkungen

Es ist jedoch wichtig zu beachten ( wie im Dokument beschrieben ), dass dies nur für .NET Core 2.0 + und .NET Standard 2.1 + gilt.

Ab heute (26. November 2019) schlägt der obige Code auch in der neuesten .NET Framework- Version fehl : 4.8 .

Wenn Sie den obigen Code in einer Konsolenanwendung ausprobieren , z. B. .NET Core 1.1 oder niedriger oder .NET Framework 4.8 oder niedriger, wird die folgende Ausnahme ausgelöst:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 
'Operator '*' cannot be applied to operands of type 'System.TimeSpan' and 'int''

Warum nicht in .NET Framework?

Um zu verstehen, warum wir den obigen Code in .NET Framework nicht verwenden können, ist es aufschlussreich zu sehen, was Immo sagt :

.NET Core ist die Open Source-, plattformübergreifende und sich schnell bewegende Version von .NET. Aufgrund seiner Nebeneinanderstellung können Änderungen vorgenommen werden, die wir nicht riskieren können, wieder auf .NET Framework anzuwenden. Dies bedeutet, dass .NET Core im Laufe der Zeit neue APIs und Sprachfunktionen erhält, die .NET Framework nicht kann. Bei Build haben wir eine Demo gezeigt, wie die Datei-APIs unter .NET Core schneller sind. Wenn wir dieselben Änderungen in .NET Framework übernehmen, können wir vorhandene Anwendungen beschädigen, und das möchten wir nicht.

Deczaloth
quelle
2

Sie müssen angeben, welches Mitglied Sie mit 5 multiplizieren möchten -> TimeSpan.TotalMinutes * 5

PedroC88
quelle
1
Dies funktioniert - aber eine schönere allgemeine Lösung besteht darin, die Zecken IMHO zu multiplizieren.
Rob Levine
1
Nein, ein TimeSpan ist ein Skalar. T * 5sollte auch die Stunden und Sekunden multiplizieren.
Henk Holterman
1
@HenkHolterman TotalMinutesist jedoch die Gesamtdauer der Zeitspanne in Minuten. Wenn die Zeitspanne also eine Stunde und 10 Minuten und 30 Sekunden darstellt, würde TotalMinutes 70,5 zurückgeben.
Phoog
1
@HenkHolterman Wie Phoog feststellt, ist die TotalMinutesEigenschaft ein Double, das die Gesamtanzahl der Minuten der gesamten Zeitspanne angibt, wobei alle anderen Felder berücksichtigt werden. Diese Lösung funktioniert genauso, Ticksscheint aber ein besserer Ansatz zu sein. Beachten Sie jedoch, dass die Ticks später in Minuten umgewandelt werden müssen, wenn Sie dem Benutzer einige sinnvolle Informationen anzeigen möchten.
PedroC88
Einverstanden reagierte ich auf den ersten Teil des Satzes. TotalMinutes ist nicht wirklich ein Compositing-Mitglied.
Henk Holterman
2

Das Problem hierbei ist, dass Sie die Zeitspanne multiplizieren möchten. Die einfachste Problemumgehung ist die Verwendung von Zecken. z.B.

 var ticks = TimeSpan.FromMinutes(1).Ticks;
 var newTimeSpan = TimeSpan.FromTicks(ticks*5);
Marcin
quelle