Apakah ada fungsi sederhana untuk pembulatan UP sebuah DateTime
ke terdekat 15 menit?
Misalnya
2011-08-11 16:59
menjadi 2011-08-11 17:00
2011-08-11 17:00
tetap sebagai 2011-08-11 17:00
2011-08-11 17:01
menjadi 2011-08-11 17:15
DateTime RoundUp(DateTime dt, TimeSpan d)
{
return new DateTime((dt.Ticks + d.Ticks - 1) / d.Ticks * d.Ticks, dt.Kind);
}
Contoh:
var dt1 = RoundUp(DateTime.Parse("2011-08-11 16:59"), TimeSpan.FromMinutes(15));
// dt1 == {11/08/2011 17:00:00}
var dt2 = RoundUp(DateTime.Parse("2011-08-11 17:00"), TimeSpan.FromMinutes(15));
// dt2 == {11/08/2011 17:00:00}
var dt3 = RoundUp(DateTime.Parse("2011-08-11 17:01"), TimeSpan.FromMinutes(15));
// dt3 == {11/08/2011 17:15:00}
DateTime RoundUp(DateTime dt, TimeSpan d) { return new DateTime(((dt.Ticks + d.Ticks - 1) / d.Ticks) * d.Ticks, dt.Kind); }
Datang dengan solusi yang tidak melibatkan mengalikan dan membagi
long
angka.Pemakaian:
sumber
%d.Ticks
diRoundUp
diperlukan?d.Ticks - (dt.Ticks % d.Ticks))
akan selalu kurang darid.Ticks
, jadi jawabannya harus sama benar?jika Anda perlu membulatkan ke interval waktu terdekat (tidak naik) maka saya sarankan untuk menggunakan yang berikut
sumber
Hasil:
sumber
2011-08-11 17:00:01
akan terpotong ke2011-08-11 17:00:00
Karena saya benci menciptakan kembali roda, saya mungkin akan mengikuti algoritma ini untuk membulatkan nilai DateTime ke peningkatan waktu tertentu (Timespan):
DateTime
nilai untuk dibulatkan menjadi nilai floating-point desimal yang mewakili jumlah keseluruhan dan fraksionalTimeSpan
unit.Math.Round()
.TimeSpan
unit.DateTime
nilai baru dari jumlah kutu bulat dan kembalikan ke pemanggil.Berikut kodenya:
sumber
DateTime
, tapi saya juga ingin kemampuan untuk putaran sampai ke kelipatanunit
. MelewatiMidpointRounding.AwayFromZero
keRound
tidak memiliki efek yang diinginkan. Apakah Anda memikirkan hal lain dengan menerimaMidpointRounding
argumen?Versi saya
Sebagai metode itu akan mengunci seperti ini
dan disebut seperti itu
sumber
Anggun?
sumber
Perhatian: rumus di atas salah, yaitu yang berikut:
harus ditulis ulang sebagai:
sumber
/ d.Ticks
membulatkan ke interval 15 menit terdekat (sebut saja "blok" ini), menambahkan hanya setengah blok tidak menjamin pembulatan ke atas. Pertimbangkan kapan Anda memiliki 4,25 blok. Jika Anda menambahkan 0,5 blok, lalu menguji berapa banyak blok bilangan bulat yang Anda miliki, Anda masih memiliki 4. Menambahkan satu centang kurang dari satu blok penuh adalah tindakan yang benar. Ini memastikan Anda selalu naik ke kisaran blok berikutnya (sebelum pembulatan ke bawah), tetapi mencegah Anda bergerak di antara blok yang tepat. (Yaitu, jika Anda menambahkan satu blok penuh ke 4.0 blok, 5.0 akan membulatkan menjadi 5, ketika Anda menginginkan 4. 4.99 akan menjadi 4.)Solusi yang lebih verbose, yang menggunakan modulo dan menghindari perhitungan yang tidak perlu.
sumber
Ini adalah solusi sederhana untuk mengumpulkan hingga 1 menit terdekat. Ini menjaga informasi TimeZone dan Jenis DateTime. Ini dapat dimodifikasi agar sesuai dengan kebutuhan Anda lebih lanjut (jika Anda perlu membulatkan ke 5 menit terdekat, dll).
sumber
Anda dapat menggunakan metode ini, ia menggunakan tanggal yang ditentukan untuk memastikan ia mempertahankan segala jenis globalisasi dan datetime yang sebelumnya ditentukan dalam objek datetime.
. Tes Biola Bersih
Jika Anda ingin menggunakan TimeSpan untuk membulatkan, Anda dapat menggunakan ini.
TimeSpan Fiddle
sumber
var d = new DateTime(2019, 04, 15, 9, 40, 0, 0);
// seharusnya 9:42 tetapi tidak satupun dari metode ini bekerja seperti itu?