Gandakan TimeSpan di .NET

87

Bagaimana cara mengalikan objek TimeSpan di C #? Dengan asumsi variabelnya durationadalah TimeSpan , saya ingin, misalnya

duration*5

Tapi itu memberi saya kesalahan "operator * tidak dapat diterapkan ke tipe TimeSpan dan int". Inilah solusi saya saat ini

duration+duration+duration+duration+duration

Tapi ini tidak mencakup kelipatan non-integer, misalnya. duration * 3.5

Kolonel Panik
sumber

Jawaban:

103

Dari artikel ini

TimeSpan duration = TimeSpan.FromMinutes(1);
duration = TimeSpan.FromTicks(duration.Ticks * 12);
Console.WriteLine(duration);     
Justin Pihony
sumber
4
Terima kasih saya menggunakanTimeSpan.FromTicks((long)(duration.Ticks*multiplier))
Kolonel Panic
2
Saya lebih suka menggunakan metode ekstensi. Seperti yang dikemukakan oleh Stephen Hewlett dalam jawabannya atas pertanyaan ini.
Mike de Klerk
11
@MikedeKlerk Setuju, tapi itu lebih gula sintaksis. OP masih perlu mengetahui akar jawabannya sehingga dapat diterapkan di dalam metode apa pun, ekstensi atau tidak
Justin Pihony
2
Terima kasih atas pujiannya, tetapi saya merasa berkewajiban untuk menunjukkan bahwa @JustinPihony menjawab hampir dua tahun sebelum saya melakukannya dan informasi dalam jawabannya yang memungkinkan saya menulis jawaban saya.
Stephen Hewlett
45

Bagi mereka yang ingin menyalin dan menempel:

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

Contoh Penggunaan:

using Utility;

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

t akan berakhir sebagai 150 detik.

Stephen Hewlett
sumber
Metode penyuluhan adalah solusi paling nyaman untuk masalah semacam ini.
Mike de Klerk
Parameter pengali dapat memiliki tipe panjang tanpa biaya tambahan.
tm1
13

The TimeSpanStruktur tidak memberikan kelebihan untuk *operator, sehingga Anda harus melakukan ini sendiri:

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

Anda dapat menggunakan data internal TimeSpan, yaitu ticks.

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

Multiply sekarang tersedia untuk TimeSpan !!!

Tetapi hanya untuk .NET Core dan .NET Standard .

Sejak .NET Core 2.0 (atau .NET Standard 2.1 ) Anda berhasil dapat menjalankan kode berikut:

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

Batasan

Namun demikian, penting untuk dicatat ( seperti yang dijelaskan dalam dokumen ) bahwa ini hanya berlaku untuk .NET Core 2.0 +, dan .NET Standard 2.1 +.

Mulai hari ini (26 November 2019) kode di atas akan gagal bahkan dalam versi .NET Framework terbaru: 4.8 .

Jika Anda mencoba kode di atas dalam aplikasi Konsol , misalnya, menjalankan .NET Core 1.1 atau yang lebih rendah, atau .NET Framework 4.8 atau lebih rendah, Anda akan melihat pengecualian berikut:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Operator' * 'tidak dapat diterapkan ke operan jenis' System.TimeSpan 'dan' int ''


Mengapa tidak di .NET Framework?

Untuk memahami mengapa kita tidak dapat menggunakan kode di atas dalam .NET Framework, sangat mencerahkan untuk melihat apa yang dikatakan Immo :

.NET Core adalah versi .NET sumber terbuka, lintas platform, dan bergerak cepat. Karena sifatnya yang berdampingan, dapat mengambil perubahan yang tidak dapat kami ambil risiko untuk menerapkan kembali ke .NET Framework. Ini berarti bahwa .NET Core akan mendapatkan API dan fitur bahasa baru dari waktu ke waktu yang tidak dapat dilakukan oleh .NET Framework. Di Build kami menunjukkan demo bagaimana API file lebih cepat di .NET Core. Jika kami memasukkan perubahan yang sama ke dalam .NET Framework, kami dapat merusak aplikasi yang ada, dan kami tidak ingin melakukannya.

Deczaloth
sumber
2

Anda perlu menentukan anggota mana yang ingin Anda kalikan dengan 5 -> TimeSpan.TotalMinutes * 5

PedroC88
sumber
1
Ini berhasil - tetapi solusi umum yang lebih baik adalah melipatgandakan kutu IMHO.
Rob Levine
1
Tidak, TimeSpan adalah skalar. T * 5harus mengalikan jam dan detik juga.
Henk Holterman
1
@HenkHolterman tetapi TotalMinutesmerupakan total durasi rentang waktu yang dinyatakan dalam menit, jadi jika rentang waktu mewakili satu jam dan 10 menit dan 30 detik, TotalMinutes akan mengembalikan 70,5.
phoog
1
@HenkHolterman Seperti catatan phoog TotalMinutesProperti adalah Double yang memberikan jumlah total menit dari seluruh TimeSpan, dengan mempertimbangkan semua bidang lainnya. Solusi ini bekerja dengan cara yang sama meskipun Tickstampaknya pendekatan yang lebih baik. Tetapi pertimbangkan bahwa Kutu nantinya perlu diubah menjadi menit jika Anda ingin menunjukkan kepada pengguna beberapa informasi yang masuk akal.
PedroC88
Setuju, saya bereaksi pada bagian pertama kalimat. TotalMinutes sebenarnya bukan anggota pengomposisian.
Henk Holterman
2

Masalahnya di sini adalah Anda ingin melipatgandakan rentang waktu. Solusi paling sederhana adalah menggunakan kutu. misalnya.

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