Moltiplica TimeSpan in .NET


87

Come si moltiplica un oggetto TimeSpan in C #? Supponendo che la variabile durationsia un TimeSpan , vorrei, ad esempio

duration*5

Ma questo mi dà un errore "l'operatore * non può essere applicato ai tipi TimeSpan e int". Ecco la mia attuale soluzione alternativa

duration+duration+duration+duration+duration

Ma questo non si estende ai multipli non interi, ad es. duration * 3.5

Risposte:


103

Da questo articolo

TimeSpan duration = TimeSpan.FromMinutes(1);
duration = TimeSpan.FromTicks(duration.Ticks * 12);
Console.WriteLine(duration);     

4
Grazie ho usatoTimeSpan.FromTicks((long)(duration.Ticks*multiplier))
Colonnello Panico

2
Preferisco usare metodi di estensione. Come suggerito da Stephen Hewlett nelle sue risposte a questa domanda.
Mike de Klerk

11
@MikedeKlerk d'accordo, ma questo è più zucchero sintattico. L'OP deve ancora conoscere la radice della risposta in modo che possa essere applicata all'interno di qualsiasi metodo, estensione o meno
Justin Pihony

2
Grazie per il complimento, ma mi sento in dovere di sottolineare che @JustinPihony ha risposto quasi due anni prima di me e sono state le informazioni nella sua risposta che mi hanno permesso di scrivere la mia.
Stephen Hewlett

45

Per coloro che desiderano copiare e incollare:

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

Utilizzo di esempio:

using Utility;

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

t finirà come 150 secondi.


I metodi di estensione sono la soluzione più conveniente a questo tipo di problemi.
Mike de Klerk

Il parametro moltiplicatore potrebbe avere un tipo lungo senza costi aggiuntivi.
tm1

13

La TimeSpanstruttura non prevede un sovraccarico per l' *operatore, quindi devi farlo tu stesso:

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


5

È possibile utilizzare i dati interni di TimeSpan, ovvero i tick.

TimeSpan day = TimeSpan.FromDays(1);
TimeSpan week = TimeSpan.FromTicks(day.Ticks * 7);

5

Multiply è ora disponibile per TimeSpan !!!

Ma solo per .NET Core e .NET Standard .

A partire da .NET Core 2.0 (o .NET Standard 2.1 ) è possibile eseguire correttamente il codice seguente:

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

Limitazioni

Tuttavia, è importante notare ( come descritto nel documento ) che questo si applica solo a .NET Core 2.0 + e .NET Standard 2.1 +.

Ad oggi (26 novembre 2019) il codice sopra riportato fallirà anche nell'ultima versione di .NET Framework : 4.8 .

Se provi il codice sopra in un'applicazione console , ad esempio, che esegue .NET Core 1.1 o versioni precedenti o .NET Framework 4.8 o versioni precedenti , verrà generata la seguente eccezione:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: "Operator" * "non può essere applicato agli operandi di tipo" System.TimeSpan "e" int "


Perché non in .NET Framework?

Per capire perché diavolo non possiamo usare il codice sopra in .NET Framework, è illuminante vedere cosa dice Immo :

.NET Core è la versione open source, multipiattaforma e in rapido movimento di .NET. A causa della sua natura side-by-side, può richiedere modifiche che non possiamo rischiare di applicare di nuovo a .NET Framework. Ciò significa che .NET Core otterrà nuove API e funzionalità del linguaggio nel tempo che .NET Framework non può. In Build abbiamo mostrato una demo in che modo le API dei file sono più veloci su .NET Core. Se inseriamo le stesse modifiche in .NET Framework, potremmo rompere le applicazioni esistenti e non vogliamo farlo.



2

È necessario specificare quale membro si desidera moltiplicare per 5 -> TimeSpan.TotalMinutes * 5


1
Questo funziona, ma una soluzione generale più carina è moltiplicare le zecche IMHO.
Rob Levine

1
No, un TimeSpan è uno scalare. T * 5dovrebbe moltiplicare anche le ore e i secondi.
Henk Holterman

1
@HenkHolterman ma TotalMinutesè la durata totale dell'intervallo di tempo espressa in minuti, quindi se l'intervallo di tempo rappresenta un'ora e 10 minuti e 30 secondi, TotalMinutes restituirebbe 70,5.
phoog

1
@HenkHolterman Come osserva phoog, la TotalMinutesproprietà è un Double che fornisce la quantità totale di minuti dell'intero TimeSpan, tenendo conto di tutti gli altri campi. Questa soluzione funziona allo stesso modo anche Ticksse sembra un approccio migliore. Ma tieni presente che in seguito le zecche dovranno essere trasformate in minuti se vuoi mostrare all'utente alcune informazioni che hanno senso.
PedroC88

D'accordo, ho reagito alla prima parte della frase. TotalMinutes non è realmente un membro di composizione.
Henk Holterman

2

Il problema qui è che vuoi moltiplicare il periodo. La soluzione più semplice è usare le zecche. per esempio.

 var ticks = TimeSpan.FromMinutes(1).Ticks;
 var newTimeSpan = TimeSpan.FromTicks(ticks*5);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.