在.NET 6中使用DateOnly和TimeOnly
千呼萬(wàn)喚始出來(lái)
在.NET 6(preview 4)中引入了兩個(gè)期待已久的類(lèi)型,將作為核心庫(kù)的一部分。DateOnly和TimeOnly允許開(kāi)發(fā)人員表示DateTime的日期或時(shí)間部分。這兩個(gè)類(lèi)型為值類(lèi)型(struct type),可以在代碼中獨(dú)立處理日期或時(shí)間概念時(shí)使用,它們定義在System命名控件中,使用它們可以與數(shù)據(jù)庫(kù)中允許表示相同類(lèi)型數(shù)據(jù)的方式保持一致。具體來(lái)說(shuō),這些類(lèi)型與SQL Server數(shù)據(jù)庫(kù)中日期和時(shí)間類(lèi)型可以很好的進(jìn)行匹配。
注意:如果你要使用這兩種類(lèi)型,需要下載并安裝.NET 6(preview 4)和Visual Studio 16.11(目前處于預(yù)覽版中)。如果你想測(cè)試一下如何使用,可以使用LinqPad進(jìn)行測(cè)試驗(yàn)證。
在.NET 6中使用DateOnly類(lèi)型
根據(jù)字面意思可以很容易看出它所要表達(dá)的意思。當(dāng)我們需要表示一個(gè)沒(méi)有時(shí)間信息的日期類(lèi)型時(shí),可以使用DateOnly。例如,我們可以在應(yīng)用程序中表示某人的出生日期。在這種情況下,我們很少需要使用到DateTime類(lèi)型的時(shí)間部分了。一個(gè)標(biāo)準(zhǔn)的解決方案時(shí)將時(shí)間設(shè)置為:00:00:00.000。但是使用DateOnly,我們可以更明確的表明我們想要的意圖。
我們可以通過(guò)年、月、日參數(shù)構(gòu)建一個(gè)DateOnly的實(shí)例。
var?date?=?new?DateOnly(2021,?5,?31);這樣,我們就創(chuàng)建了一個(gè)表示2021年5月31日的日期類(lèi)型。在內(nèi)部,DataOnly結(jié)構(gòu)使用一個(gè)整數(shù)來(lái)跟蹤一個(gè)有效天數(shù)的時(shí)間范圍:0(映射為0001年1月1日)-3652058(映射為9999年12月31日)。
通常情況下,我們會(huì)從一個(gè)現(xiàn)有的DateTime類(lèi)型的實(shí)例開(kāi)始,希望從它創(chuàng)建一個(gè)DateOnly實(shí)例。為了實(shí)現(xiàn)這一點(diǎn),我們可以調(diào)用FromDateTime方法。
var?currentDateOnly?=?DateOnly.FromDateTime(DateTime.Now);與現(xiàn)有的DateTime類(lèi)型一樣,我們也可以使用Parse或TryParse方法將表示日期的字符串解析為DateOnly類(lèi)型,這兩個(gè)方法可能會(huì)拋出異常,或返回指示成功或失敗的bool值。
if?(DateOnly.TryParse("28/09/1984",?new?CultureInfo("en-GB"),?DateTimeStyles.None,?out?var?result)) {Console.WriteLine($"{result.Year}-{result.Month}-{result.Day}"); }上面的代碼嘗試從第一個(gè)參數(shù)(日期的字符串表示)解析日期。由于不同的國(guó)家和地區(qū)對(duì)日期的解釋不同,因此日期的解析可能或受到文化的影響。在這個(gè)例子中,明確提供CultureInfo選項(xiàng),以確保它使用日/月/年的格式從字符串中正確解析。在成功解析成DateOnly實(shí)例的情況下,它將被寫(xiě)入控制臺(tái)。再一次強(qiáng)調(diào):CultureInfo選擇在這里扮演著重要角色。在本例中,將使用正在運(yùn)行的線(xiàn)程的當(dāng)前區(qū)域性來(lái)確定所使用的格式。根據(jù)系統(tǒng)配置,在應(yīng)用程序線(xiàn)程在en-GB下運(yùn)行。因此字符串被正確格式化。在LinqPad輸出結(jié)果:
我們還可以向DateOnly實(shí)例中調(diào)用AddDays、AddMonths和AddYears方法,以創(chuàng)建一個(gè)新的日期類(lèi)型的實(shí)例。
var?newDateOnly?=?date.AddDays(1).AddMonths(1).AddYears(1);在.NET 6中使用TimeOnly類(lèi)型
TimeOnly結(jié)構(gòu)體用于表示一個(gè)與日期無(wú)關(guān)的一個(gè)時(shí)間類(lèi)型。例如,想象創(chuàng)建一個(gè)鬧鐘應(yīng)用程序,讓用戶(hù)創(chuàng)建一個(gè)重復(fù)出現(xiàn)的鬧鐘。在這種情況下,我們要存儲(chǔ)一天中報(bào)警應(yīng)該想起的時(shí)間,但這個(gè)時(shí)間和日期是沒(méi)有關(guān)系的。TimeOnly類(lèi)型有幾個(gè)構(gòu)造方法重載。我認(rèn)為大多數(shù)開(kāi)發(fā)者會(huì)使用的且更常見(jiàn)的方法是允許我們創(chuàng)建一個(gè)可以小時(shí)分鐘,小時(shí)分鐘秒數(shù)、小時(shí)分鐘秒數(shù)毫秒數(shù)方法的時(shí)間類(lèi)型。
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分,我們可以創(chuàng)建以下TimeOnly的實(shí)例。
var?startTime?=?new?TimeOnly(10,?30);在這里,小時(shí)采用24小時(shí)制格式,這樣 1 PM 就是13時(shí)。
在內(nèi)部,TimeOnly存儲(chǔ)了一個(gè)long類(lèi)型,它表示自定義時(shí)間從凌晨后經(jīng)過(guò)的Ticks(100納秒一個(gè)tick)。例如,凌晨1點(diǎn)時(shí)一天中的第一個(gè)小時(shí),因此,從凌晨開(kāi)始就有360億個(gè)Tick(00:00:00.0000000)。雖然我們可以通過(guò)提供Ticks作為參數(shù)來(lái)構(gòu)造TimeOnly。但這個(gè)實(shí)現(xiàn)細(xì)節(jié)對(duì)于一般使用來(lái)說(shuō)并不是必需的。
public?TimeOnly(long?ticks);在定義了開(kāi)始時(shí)間之后,我們可以使用另一個(gè)TimeOnly實(shí)例定義一個(gè)結(jié)束時(shí)間為5PM。
var?endTime?=?new?TimeOnly(17,?00,?00);現(xiàn)在就可以對(duì)這些TimeOnly實(shí)例進(jìn)行數(shù)學(xué)操作,比如計(jì)算差。
var?diff?=?endTime?-?startTime;該操作返回類(lèi)型是TimeSpan,記錄了兩個(gè)TimeOnly值之間相差的小時(shí)數(shù)。可以看LinqPad的輸出結(jié)果。
我們可以執(zhí)行的另一個(gè)檢查時(shí)識(shí)別特定的TimeOnly是否在時(shí)間窗口內(nèi)。例如,假設(shè)我們想要檢查當(dāng)前時(shí)間是否在我們定義的開(kāi)始時(shí)間和結(jié)束時(shí)間之間。與DateOnly一樣,我們可以使用FromDateTime靜態(tài)方法將現(xiàn)有的DateTime轉(zhuǎn)化為T(mén)imeOnly。
var?currentTime?=?TimeOnly.FromDateTime(DateTime.Now); var?isBetween?=?currentTime.IsBetween(startTime,?endTime); Console.WriteLine($"Current?time?{(isBetween???"is"?:?"is?not")}?between?start?and?end");上面的代碼將輸出到控制臺(tái),以確定當(dāng)前時(shí)間是否在10:30(10:30 AM)和17:00(5 PM)之間。LinqPad輸出的結(jié)果進(jìn)行了稍微的改變,用來(lái)輸出當(dāng)前時(shí)間。
方法IsBetween()可以接受兩個(gè)參數(shù),正常的時(shí)間范圍,如我們前面的示例中使用的范圍。同樣可以接受跨凌晨的時(shí)間范圍,如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?endLinqPad中的最后一行的輸出內(nèi)容。
TimeOnly還包括用于比較使用循環(huán)時(shí)鐘的時(shí)間操作符。
var?startTime?=?new?TimeOnly(08,?00); var?endTime?=?new?TimeOnly(09,?00);Console.WriteLine($"{startTime?<?endTime}"); //?Output?=?True這段代碼檢查上午8點(diǎn)是否早于上午9點(diǎn),顯然是早于9點(diǎn)的。
總結(jié)
面向 .NET 6 的新應(yīng)用程序中,如果您的數(shù)據(jù)需要獨(dú)立表示日期或時(shí)間,那么 DateOnly 和 TimeOnly 值得考慮。
你喜歡這篇文章嗎?覺(jué)得它有用嗎?如果有,請(qǐng)考慮支持我
廣告時(shí)間:如果你身邊有正在做化妝品的朋友,可以給他們推薦一下。或者自己的女朋友正在為美麗而煩惱,請(qǐng)推薦給你的女朋友!
— END —
「擴(kuò)展閱讀」
Xamarin.Forms: 無(wú)限滾動(dòng)的ListView(懶加載方式)
[GitHub] 75+的 C# 數(shù)據(jù)結(jié)構(gòu)和算法實(shí)現(xiàn)
誰(shuí)說(shuō).NET不適合搞BD,ML、AI
推薦一個(gè)集錄屏、截圖、音頻于一體的軟件給大家
10個(gè)用于C#.NET開(kāi)發(fā)的基本調(diào)試工具
Xamarin.Forms 二維碼掃描實(shí)踐
在Asp.Net Core MVC 開(kāi)發(fā)過(guò)程中遇到的問(wèn)題總結(jié)
前端小白在asp.net core mvc中使用ECharts
基于Asp.Net Core MVC和AdminLTE的響應(yīng)式管理后臺(tái)之側(cè)邊欄處理
[譯]如何在C#中調(diào)試LINQ查詢(xún)
C# 語(yǔ)言性能提升方法
使用MQTTnet搭建Mqtt服務(wù)器
OxyPlot在WinForm中的應(yīng)用
「公眾號(hào)推薦」
回復(fù):「rdm」?獲取Redis Desktop Manager版的安裝包
回復(fù):「redis」?獲取5.0.9版的Windows安裝包(exe)
回復(fù):「ca」 獲取 ?截圖、GIF等工具三件套,便攜版和安裝版全部包括
「加號(hào)主回復(fù)”入群“」即可加入群聊
總結(jié)
以上是生活随笔為你收集整理的在.NET 6中使用DateOnly和TimeOnly的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: out参数不用赋值?这么神奇吗!
- 下一篇: asp.net ajax控件工具集 Au