今日不可轉載,可在兒童節當天或之後在公眾號申請白名單。
千呼萬喚始出來
在.NET 6(preview 4)
中引入了兩個期待已久的型別,將作為核心庫的一部分。DateOnly
和TimeOnly
允許開發人員表示DateTime
的日期或時間部分。這兩個型別為值型別(struct type),可以在程式碼中獨立處理日期或時間概念時使用,它們定義在System命名控制元件中,使用它們可以與資料庫中允許表示相同型別資料的方式保持一致。具體來說,這些型別與SQL Server資料庫中日期和時間型別可以很好的進行匹配。
注意:如果你要使用這兩種型別,需要下載並安裝.NET 6(preview 4)
和Visual Studio 16.11
(目前處於預覽版中)。如果你想測試一下如何使用,可以使用LinqPad
進行測試驗證。
在.NET 6
中使用DatetOnly
型別
根據字面意思可以很容易看出它所要表達的意思。當我們需要表示一個沒有時間資訊的日期型別時,可以使用DateOnly
。例如,我們可以在應用程式中表示某人的出生日期。在這種情況下,我們很少需要使用到DateTime
型別的時間部分了。一個標準的解決方案時將時間設定為:00:00:00.000。但是使用DateOnly
,我們可以更明確的表明我們想要的意圖。
我們可以通過年、月、日引數構建一個DateOnly
的例項。
var date = new DateOnly(2021, 5, 31);
這樣,我們就建立了一個表示2021年5月31日的日期型別。在內部,DataOnly
結構使用一個整數來跟蹤一個有效天數的時間範圍:0(對映為0001年1月1日)-3652058(對映為9999年12月31日)。
通常情況下,我們會從一個現有的DateTime
型別的例項開始,希望從它建立一個DateOnly
例項。為了實現這一點,我們可以呼叫FromDateTime
方法。
var currentDateOnly = DateOnly.FromDateTime(DateTime.Now);
與現有的DateTime
型別一樣,我們也可以使用Parse
或TryParse
方法將表示日期的字串解析為DateOnly
型別,這兩個方法可能會丟擲異常,或返回指示成功或失敗的bool
值。
if (DateOnly.TryParse("28/09/1984", new CultureInfo("en-GB"), DateTimeStyles.None, out var result))
{
Console.WriteLine($"{result.Year}-{result.Month}-{result.Day}");
}
上面的程式碼嘗試從第一個引數(日期的字串表示)解析日期。由於不同的國家和地區對日期的解釋不同,因此日期的解析可能或受到文化的影響。在這個例子中,明確提供CultureInfo
選項,以確保它使用日/月/年的格式從字串中正確解析。
在成功解析成DateOnly例項的情況下,它將被寫入控制檯。再一次強調:CultureInfo
選擇在這裡扮演著重要角色。在本例中,將使用正在執行的執行緒的當前區域性來確定所使用的格式。根據系統配置,在應用程式執行緒在en-GB
下執行。因此字串被正確格式化。在LinqPad
輸出結果:
我們還可以向DateOnly例項中呼叫AddDays
、AddMonths
和AddYears
方法,以建立一個新的日期型別的例項。
var newDateOnly = date.AddDays(1).AddMonths(1).AddYears(1);
在.NET 6
中使用TimeOnly
型別
TimeOnly
結構體用於表示一個與日期無關的一個時間型別。例如,想象建立一個鬧鐘應用程式,讓使用者建立一個重複出現的鬧鐘。在這種情況下,我們要儲存一天中報警應該想起的時間,但這個時間和日期是沒有關係的。
TimeOnly
型別有幾個構造方法過載。我認為大多數開發者會使用的且更常見的方法是允許我們建立一個可以小時分鐘,小時分鐘秒數、小時分鐘秒數毫秒數方法的時間型別。
public TimeOnly(int hour, int minute)
public TimeOnly(int hour, int minute, int second)
public TimeOnly(int hour, int minute, int second, int millisecond)
例如,為了表示上午10:30分,我們可以建立以下TimeOnly
的例項。
var startTime = new TimeOnly(10, 30);
在這裡,小時採用24
小時制格式,這樣 1 PM
就是13時
。
在內部,TimeOnly
儲存了一個long
型別,它表示自定義時間從凌晨後經過的Ticks
(100納秒一個tick)。例如,凌晨1點時一天中的第一個小時,因此,從凌晨開始就有360億個Tick(00:00:00.0000000)。雖然我們可以通過提供Ticks
作為引數來構造TimeOnly
。但這個實現細節對於一般使用來說並不是必需的。
public TimeOnly(long ticks);
在定義了開始時間之後,我們可以使用另一個TimeOnly
例項定義一個結束時間為5PM。
var endTime = new TimeOnly(17, 00, 00);
現在就可以對這些TimeOnly
例項進行數學操作,比如計算差。
var diff = endTime - startTime;
該操作返回型別是TimeSpan
,記錄了兩個TimeOnly
值之間相差的小時數。可以看LinqPad
的輸出結果。
我們可以執行的另一個檢查時識別特定的TimeOnly
是否在時間視窗內。例如,假設我們想要檢查當前時間是否在我們定義的開始時間和結束時間之間。與DateOnly
一樣,我們可以使用FromDateTime
靜態方法將現有的DateTime
轉化為TimeOnly
。
var currentTime = TimeOnly.FromDateTime(DateTime.Now);
var isBetween = currentTime.IsBetween(startTime, endTime);
Console.WriteLine($"Current time {(isBetween ? "is" : "is not")} between start and end");
上面的程式碼將輸出到控制檯,以確定當前時間是否在10:30(10:30 AM)
和17:00(5 PM)
之間。LinqPad輸出的結果進行了稍微的改變,用來輸出當前時間。
方法IsBetween()
可以接受兩個引數,正常的時間範圍,如我們前面的示例中使用的範圍。同樣可以接受跨凌晨的時間範圍,如22:00-02:00。
var startTime = new TimeOnly(22, 00);
var endTime = new TimeOnly(02, 00);
var now = new TimeOnly(23, 25);
var isBetween = now.IsBetween(startTime, endTime);
Console.WriteLine($"Current time {(isBetween ? "is" : "is not")} between start and end");
// Output = Current time is between start and end
LinqPad
中的最後一行的輸出內容。
TimeOnly
還包括用於比較使用迴圈時鐘的時間操作符。
var startTime = new TimeOnly(08, 00);
var endTime = new TimeOnly(09, 00);
Console.WriteLine($"{startTime < endTime}");
// Output = True
這段程式碼檢查上午8點是否早於上午9點,顯然是早於9點的。
總結
面向 .NET 6
的新應用程式中,如果您的資料需要獨立表示日期或時間,那麼 DateOnly
和 TimeOnly
值得考慮。
你喜歡這篇文章嗎?覺得它有用嗎?如果有,請考慮支援我,關注一下我的公眾號