C#快速入門教程(25)—— 日期與時間
在System名稱空間裡定義了日期和時間處理的基礎資源,如DateTime和TimeSpan結構型別;本課,除了使用這些基礎資源,我們還將討論如何獲取中國農曆資訊,首先,我們從DateTime結構的使用開始。
DateTime結構
DateTime結構中的MinValue和MaxValue兩個欄位,分別定義了處理日期和時間的最小值和最大值,其中,MinValue表示公元0001年1月1日0時0分0秒。此外,在.NET Framework中處理時間的最小單位是Tick,它表示萬之一秒(即100毫微秒),在DateTime中的Ticks屬性則表示儲存時間距離DateTime.MinValue值的Tick值。
除了Ticks屬性,我們常用用的屬性還有Year、Month、Day、Hour、Minute、Second、Millisecond等。獲取一個時間點時,可以通過建構函式、Now屬性、Today屬性等,其中:
- Now屬性可以獲取計算機的當前日期和時間。
- Today屬性獲取計算當前日期,其中的時間設定為0點0分0秒。
使用DateTime結構的建構函式時,可以使用多個版本,常用的有:
- DateTime(long),使用Tick值初始化時間。
- DateTime(int,int,int),使用年、月、日初始化時間。
- DateTime(int,int,int,int,int,int),使用年、月、日、時、分、秒初始化時間。
獲取時間值後,還可以使用一些方法顯示為常用的格式,如:
- ToLongDateString(),返回長日期格式字串。
- ToShortDateString(),返回短日期格式字串。
- ToLongTimeString(),返回長時間格式字串。
- ToShortTimeString(),返回短時間格式字串。
下面的程式碼演示了這四個方法的輸出結果,請注意,其輸出格式預設使用計算機系統設定的區域中的日期時間格式。
static void Main(string[] args)
{
DateTime dt = new DateTime(2018, 9, 23, 11, 16, 30);
Console.WriteLine(dt.ToLongDateString());
Console.WriteLine(dt.ToShortDateString());
Console.WriteLine(dt.ToLongTimeString());
Console.WriteLine(dt.ToShortTimeString());
}
我的計算機區域設定當然是中國,程式碼輸出結果如下圖所示。
除獲取日期和時間資訊,我們還可以通過DateTime結構進行一些簡單的日期和時間推算,如獲取某個時間點早一些或晚一些時間點,此時,可以使用一系列的AddXXX()方法,如下面的程式碼,我們使用AddDays()推算早三天和晚三天的時間點。
static void Main(string[] args)
{
DateTime dt = new DateTime(2018, 9, 23, 11, 16, 30);
Console.WriteLine(dt.AddDays(-3).ToString());
Console.WriteLine(dt.AddDays(3.5).ToString());
}
程式碼執行結果如下圖所示。
我們可以看到,當AddXXX()方法的引數為負數時,就是推算早一些的時間點,而引數為正數時則是推算晚一些的時間點。除了使用DateTime結構中的AddXXX()方法進行日期和時間的推算,我們還可以藉助TimeSpan結構進行日期和時間的計算工作。
TimeSpan結構
下面的程式碼,我們使用TimeSpan結構進行DateTime資料的加、減運算。
static void Main(string[] args)
{
DateTime dt1 = new DateTime(2018, 9, 23, 11, 16, 00);
TimeSpan ts = new TimeSpan(1, 30, 0);
DateTime dt2 = dt1 + ts;
Console.WriteLine(dt2.ToString());
DateTime dt3 = dt1 - ts;
Console.WriteLine(dt3.ToString());
}
本例中,我們定義的TimeSpan為1小時30分,然後,使用dt1分別進行加(晚一些)、減(早一些)運算,執行結果如下圖所示。
實際應用中,我們使用兩個DateTime資料進行加、減運算時,也會返回一個TimeSpan資料,此時,可以獲取兩個時間點間隔的小時、分、秒等資料,如下面的程式碼。
static void Main(string[] args)
{
DateTime dt1 = new DateTime(2018, 9, 23, 11, 16, 00);
DateTime dt2 = new DateTime(2018, 9, 26, 15, 36, 25);
TimeSpan ts = dt2 - dt1;
Console.WriteLine(ts.Days);
Console.WriteLine(ts.Hours);
Console.WriteLine(ts.Minutes);
Console.WriteLine(ts.Seconds);
}
本例顯示了兩個時間點分別計算的天數、小時數、分鐘數和秒數,執行結果如下圖所示。
此外,如果需要兩個時間點完整的間隔資料,可以使用TimeSpan結構中的Ticks屬性獲取。
獲取中國農曆資訊
世界上很多文明都有自己的歷法,中國的農曆就是其中之一,相信大家在春節時就會感覺到其威力有多大。在.NET Framework類庫中,包含了處理各種曆法的資源,它們包含在System.Globalization名稱空間,以下程式碼請注意引用此名稱空間。
下面的程式碼,我們首先計算出農曆所需要的資料。
/*
* CChineseCalendar類,處理農曆
*
*/
using System;
using System.Globalization;
namespace ConsoleTest
{
public class CChineseCalendar
{
private DateTime myDate;
// 建構函式
public CChineseCalendar(DateTime dt)
{
myDate = dt;
SetLunar();
}
//
public CChineseCalendar() : this(DateTime.Now)
{ }
//
public CChineseCalendar(int year, int month, int day)
:this(new DateTime(year, month, day))
{ }
// 計算農曆資訊
private void SetLunar()
{
ChineseLunisolarCalendar cale =
new ChineseLunisolarCalendar();
// 甲子年份
Year =
cale.GetSexagenaryYear(myDate);
// 地支
TerrestrialBranch =
cale.GetTerrestrialBranch(Year);
// 天干
CelestialStem =
cale.GetCelestialStem(Year);
// 月份(1-13),注意處理閏月情況
Month = cale.GetMonth(myDate);
// 閏月是第幾個月,注意冬月和臘月在陽曆第二年的情況
// 如是8就是閏七月
if (Month > 10 && myDate.Month < 3)
LeapMonth = cale.GetLeapMonth(myDate.Year - 1);
else
LeapMonth = cale.GetLeapMonth(myDate.Year);
// 日子
Day = cale.GetDayOfMonth(myDate);
}
//
public int Year { get; private set; }
public int Month { get;private set; }
public int LeapMonth { get; private set; }
public int Day { get; private set; }
public int TerrestrialBranch { get; private set; }
public int CelestialStem { get; private set; }
//
}// end class CChineseCalendar
}
程式碼中,我們定義了一些屬性,如:
- Year屬性,農曆年份,表示甲子中的第幾年,取值從1到60。
- Month屬性,農曆月份值,取值從1到13,注意農曆有閏月的情況。
- LeapMonth屬性,閏月值,如年份中沒有閏月為0,如為8則表示閏7月,以此類推。如果陽曆為一月或二月,則應注意是不為前一年的冬月或臘月,此時,計算閏月值需要使用前一年的陽曆年份。
- Day屬性,農曆日期,如初一為1,取值從1到30。
- TerrestrialBranch屬性,地支值,1到12,同時分別對應了十二生肖。
- CelestialStem屬性,天干值,1到10。
關鍵的資料計算都放在SetLunar()方法中,其中關於各項資料的獲取請注意引數的不同,有的是使用陽曆日期(DateTime型別),有的是使用甲子年份,有的是使用陽曆年份。私有欄位myDate則用於儲存物件中處理的陽曆日期值。
此外,在CChineseCalendar類中還定義了三個建構函式,分別是:
- CChineseCalendar(DateTime dt),通過DateTime資料構建物件。
- CChineseCalendar(),通過計算機當前時間構建物件。
- CChineseCalendar(int year, int month, int day),通過年、月、日構建物件。
接下來,我們可以通過獲取的相關資料,以合理的形式顯示出農曆資訊,如下面的程式碼,首先是年份名稱的顯示。
/* 年份名稱 */
private static string[] yearNames = {"",
"甲子","乙丑","丙寅","丁卯","戊辰","己巳","庚午","辛未","壬申","癸酉",
"甲戌","乙亥","丙子","丁丑","戊寅","己卯","庚辰","辛巳","壬午","癸未",
"甲申","乙酉","丙戌","丁亥","戊子","己丑","庚寅","辛卯","壬辰","癸巳",
"甲午","乙未","丙申","丁酉","戊戌","己亥","庚子","辛丑","壬寅","癸卯",
"甲辰","乙巳","丙午","丁未","戊申","己酉","庚戌","辛亥","壬子","癸丑",
"甲寅","乙卯","丙辰","丁巳","戊午","己未","庚申","辛酉","壬戌","癸亥"};
//
public string YearName
{
get { return yearNames[Year]; }
}
程式碼中,我們定義了yearNames資料,用於儲存甲子的60個年份名稱;請注意,陣列的第一個成員定義為空字元中,這裡只是一個佔位,這樣就可以直接使用年份的值(1到60)作為索引值使用了。
月份和日期的名稱獲取與年份名稱類似,只是需要注意,月份要處理閏月的情況,如下面的程式碼。
/* 月份名稱 */
private static string[] monthNames =
{"", "正月", "二月", "三月", "四月", "五月", "六月",
"七月", "八月", "九月", "十月", "冬月", "臘月"};
// 給出當前月份名稱
public string MonthName
{
get
{
if (LeapMonth <= 0 || Month < LeapMonth)
return monthNames[Month];
else if (LeapMonth == Month)
return CStr.Append("閏", monthNames[Month - 1]);
else
return monthNames[Month - 1];
}
}
/* 日子名稱 */
private static string[] dayNames =
{"", "初一", "初二", "初三", "初四", "初五",
"初六", "初七", "初八", "初九", "初十",
"十一", "十二", "十三", "十四", "十五",
"十六", "十七", "十八", "十九", "二十",
"廿一", "廿二", "廿三", "廿四", "廿五",
"廿六", "廿七", "廿八", "廿九", "三十"};
// 當前日期名稱
public string DayName
{
get { return dayNames[Day]; }
}
下面是通過地支的值獲取十二生肖名稱的程式碼。
// 生肖對應地支
private static string[] animalNames = {"",
"鼠","牛","虎","兔","龍","蛇","馬","羊","猴","雞","狗","豬" };
//
public string AnimalName
{
get { return animalNames[TerrestrialBranch]; }
}
//
public int Animal
{
get { return TerrestrialBranch; }
}
最後,我們定義一個ToStr()方法,用於顯示完成的農曆資訊,如下面的程式碼。
//
public string ToStr()
{
return "{0}({1})年 {2}{3}".Combine(
YearName, AnimalName, MonthName, DayName);
}
下面,我們測試CChineseCalendar類的使用。
static void Main(string[] args)
{
DateTime dt1 = new DateTime(2018, 9, 23, 11, 16, 00);
CChineseCalendar cale = new CChineseCalendar(dt1);
Console.WriteLine(cale.ToStr());
}
程式碼執行結果如下圖所示。
實際應用中,大家還可以根據需要擴充套件CChineseCalendar類的功能。
CHY軟體小屋原創作品!
相關文章
- 《C#快速入門教程》目錄C#
- C#快速入門教程(16)—— 介面C#
- C#快速入門教程(6)——方法C#
- C#快速入門教程(19)—— 索引器與陣列C#索引陣列
- C#快速入門教程(5)——欄位與屬性C#
- C#快速入門教程(2)——程式碼與測試C#
- [C#]C#時間日期操作C#
- C#快速入門教程(20)—— 字串與正規表示式C#字串
- C#快速入門教程(26)—— 繪圖C#繪圖
- C#快速入門教程(21)—— 泛型C#泛型
- C#快速入門教程(15)—— 繼承C#繼承
- C#快速入門教程(8)——整數C#
- C#快速入門教程(24)—— 路徑、目錄與檔案C#
- C#快速入門教程(17)—— 委託、事件與Lambda表示式C#事件
- C#快速入門教程(28)—— ADO.NETC#
- C#快速入門教程(22)—— 常用集合型別C#型別
- C#快速入門教程(30)—— 繼續學習C#
- C#快速入門教程(18)—— 異常處理C#
- C#快速入門教程(12)—— if語句結構C#
- C#快速入門教程(10)——布林型別與布林運算C#型別
- C#快速入門教程(27)—— SQL Server資料庫C#SQLServer資料庫
- C#快速入門教程(11)—— 字元和字串型別C#字元字串型別
- C#快速入門教程(13)—— switch語句結構C#
- C#快速入門教程(7)——資料型別概述C#資料型別
- TensorFlow快速入門與實戰-彭靖田-極客時間
- Unix 時間戳與日期時間戳
- C#快速入門教程(23)—— using語句和IDisposable介面C#
- C#快速入門教程(14)—— 迴圈語句結構C#
- C#快速入門教程(4)——類成員的作用域C#
- C#快速入門教程(1)——物件導向程式設計C#物件程式設計
- Materialize快速入門教程
- C#快速入門教程(29)—— ADO.NET離線元件與資料繫結C#元件
- C# 12 Blazor入門教程C#Blazor
- Jupyter notebook快速入門教程
- c#入門教程(菜鳥級)C#
- Java 日期和時間 API:實用技巧與示例 - 輕鬆處理日期和時間JavaAPI
- 快應用快速入門教程
- go語言快速入門教程Go