Nhân khoảng thời gian trong .NET


86

Làm cách nào để nhân một đối tượng TimeSpan trong C #? Giả sử biến durationTimeSpan , tôi muốn, chẳng hạn

duration*5

Nhưng điều đó mang lại cho tôi một lỗi "không thể áp dụng toán tử * cho các loại TimeSpan và int". Đây là giải pháp hiện tại của tôi

duration+duration+duration+duration+duration

Nhưng điều này không mở rộng đến bội số không phải số nguyên, ví dụ. duration * 3.5


5
Đây là một yêu cầu thực sự hiển nhiên và đơn giản để thực hiện. Tôi tự hỏi tại sao MS không nghĩ đến việc bao gồm nhân và chia như các toán tử tiêu chuẩn?
Andy

Câu trả lời:


103

Từ bài báo này

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

4
Cảm ơn tôi đã sử dụngTimeSpan.FromTicks((long)(duration.Ticks*multiplier))
Colonel Panic

2
Tôi muốn sử dụng các phương pháp mở rộng. Giống như gợi ý của Stephen Hewlett trong câu trả lời của anh ấy cho câu hỏi này.
Mike de Klerk

11
@MikedeKlerk Đồng ý, nhưng đó là đường cú pháp hơn. OP vẫn cần biết gốc rễ của câu trả lời để nó có thể được áp dụng bên trong bất kỳ phương pháp nào, tiện ích mở rộng hay không
Justin Pihony

2
Cảm ơn bạn đã khen ngợi, nhưng tôi cảm thấy có nghĩa vụ phải chỉ ra rằng @JustinPihony đã trả lời gần hai năm trước khi tôi trả lời và chính thông tin trong câu trả lời của anh ấy đã cho phép tôi viết bài của mình.
Stephen Hewlett,

45

Đối với những người muốn sao chép và dán:

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

Cách sử dụng ví dụ:

using Utility;

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

t sẽ kết thúc là 150 giây.


Các phương pháp mở rộng là giải pháp thuận tiện nhất cho những loại vấn đề này.
Mike de Klerk

Tham số hệ số có thể có giá trị dài mà không có chi phí bổ sung.
tm1

13

Các TimeSpancấu trúc không cung cấp một tình trạng quá tải cho các *nhà điều hành, vì vậy bạn phải làm cho mình này:

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


5

Bạn có thể sử dụng dữ liệu nội bộ của TimeSpan, cụ thể là tích tắc.

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


3

Nhân hiện có sẵn cho TimeSpan !!!

Nhưng chỉ dành cho .NET Core.NET Standard .

.NET Core 2.0 (hoặc .NET Standard 2.1 ), bạn có thể chạy thành công mã sau:

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

Hạn chế

Tuy nhiên, điều quan trọng cần lưu ý ( như được mô tả trong tài liệu ) rằng điều này chỉ áp dụng cho .NET Core 2.0 + và .NET Standard 2.1 +.

Kể từ hôm nay (ngày 26 tháng 11 năm 2019), mã trên sẽ không thành công ngay cả trong phiên bản .NET Framework mới nhất: 4.8 .

Nếu bạn thử mã ở trên trong một ứng dụng Bảng điều khiển , chẳng hạn như đang chạy .NET Core 1.1 trở xuống hoặc .NET Framework 4.8 trở xuống, bạn sẽ gặp phải ngoại lệ sau:

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

Tại sao không có trong .NET Framework?

Để hiểu tại sao trên trái đất, chúng ta không thể sử dụng đoạn mã trên trong .NET Framework, thật tuyệt khi xem Immo nói :

.NET Core là phiên bản mã nguồn mở, đa nền tảng và di chuyển nhanh của .NET. Do tính chất song song của nó, nó có thể có những thay đổi mà chúng tôi không thể mạo hiểm áp dụng lại .NET Framework. Điều này có nghĩa là .NET Core sẽ nhận được các API mới và các tính năng ngôn ngữ theo thời gian mà .NET Framework không có được. Tại Build, chúng tôi đã giới thiệu bản demo cách các API tệp nhanh hơn trên .NET Core. Nếu chúng tôi đưa những thay đổi tương tự vào .NET Framework, chúng tôi có thể phá vỡ các ứng dụng hiện có và chúng tôi không muốn làm điều đó.


2

Bạn cần chỉ định thành viên mà bạn muốn nhân với 5 -> TimeSpan.TotalMinutes * 5


1
Điều này thực sự hiệu quả - nhưng một giải pháp chung tốt hơn là nhân số bọ ve IMHO.
Rob Levine

1
Không, TimeSpan là một đại lượng vô hướng. T * 5cũng nên nhân giờ và giây.
Henk Holterman

1
@HenkHolterman nhưng TotalMinuteslà tổng thời lượng của khoảng thời gian được biểu thị bằng phút, vì vậy nếu khoảng thời gian biểu thị một giờ 10 phút 30 giây, TotalMinutes sẽ trả về 70,5.
phoog

1
@HenkHolterman Như phoog lưu ý rằng TotalMinutesThuộc tính là một Nhân đôi cho tổng số phút của toàn bộ TimeSpan, có tính đến tất cả các trường khác. Giải pháp này hoạt động tương tự mặc dù Tickscó vẻ như là một cách tiếp cận tốt hơn. Nhưng hãy lưu ý rằng các Ticks sau này sẽ cần được chuyển thành phút nếu bạn muốn hiển thị cho người dùng một số thông tin có ý nghĩa.
PedroC88

Đồng ý, tôi phản ứng với phần đầu tiên của câu. TotalMinutes không thực sự là một thành viên tổng hợp.
Henk Holterman

2

Vấn đề ở đây là bạn muốn nhân khoảng thời gian. Cách giải quyết đơn giản nhất là sử dụng bọ ve. ví dụ.

 var ticks = TimeSpan.FromMinutes(1).Ticks;
 var newTimeSpan = TimeSpan.FromTicks(ticks*5);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.