System.DateUtils Misc functions部分

其實這個部分的函數大部分都是依賴於幾個基礎判斷函數,其餘函數使用不一樣參數解析爲這幾個基礎判斷函數所需的參數,而後返回這幾個基礎函數的調用結果而已.例如IsToday是返回的IsSameDay的結果,參數1爲IsToday函數的參數,參數2爲系統函數Date;還有Tomorrow和Yesterday還有Today,這三個方法裏都是使用系統預約義函數Date獲取當前時間,Today直接返回這個函數的結果,而Tommorrow和Yesterday則是返回Date函數的結果+1和-1.windows

同時咱們還發現,這幾個基礎函數其實都是先預約義一些合法值範圍的數組常量或其它類型的常量,在基礎函數中先對參數解析,而後根據條件判斷其值是否在預約義的常量中,並返回判斷的結果值(若是須要返回天數或星期數之類的,也是根據參數返回對應預約義數組常量下標內元素值,或預約義的常量).
數組

如下是我寫的部分代碼示例,由於整個單元文件代碼字數太多,沒法在一篇文章中存放,因此我把對應的單元文件.pas和窗體文件.dfm放在了代碼分享處,想查看全部源碼的請移步Misc functions部分函數使用示例及說明
函數

procedure TFMain.btnDaysInMonthClick(Sender: TObject);
var
  dBefore: TDateTime;
begin
  //DaysInMonth:返回日期參數所在年的總天數
  dBefore := StrToDateTime(sDate, FDateFormatSetting);
  //咱們來看看DaysInMonth的實現System.DateUtils 第657行
  {
  function DaysInMonth(const AValue: TDateTime): Word;
  var
    LYear, LMonth, LDay: Word;
  begin
    //DaysInAMonth定義在System.DateUtils第665行
    //由於DaysInAMonth參數爲拆分後的年和月,因此第一步先把日期拆分紅年\月\日三個參數
    //DaysInAMonth裏面的實現類同與DaysInAYear,根據平年閏年返回預約義數組的某個下標值
    //下面這個數組定義在System.SysUtils第2770行
    //MonthDays: array [Boolean] of TDayTable =
    //  ((31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
    //  (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));
    DecodeDate(AValue, LYear, LMonth, LDay);
    Result := DaysInAMonth(LYear, LMonth);
  end;
  }
  MMOResult.Lines.Add('(DaysInMonth)日期參數[' + sDate + '],本年度本月份共有:'
    + IntToStr(DaysInMonth(dBefore)) + '天');
end;

procedure TFMain.btnDaysInAMonthClick(Sender: TObject);
var
  dBefore: TDateTime;
  nYear, nMonth, nDay: Word;
begin
  //DaysInAMonth:返回年份參數+中月份參數的總天數
  dBefore := StrToDateTime(sDate, FDateFormatSetting);
  DecodeDate(dBefore, nYear, nMonth, nDay);
  //咱們來看看DaysInAMonth的實現System.DateUtils 第665行
  {
  function DaysInAMonth(const AYear, AMonth: Word): Word;
  begin
    //這裏根據平年或閏年+月份,返回一個預約義的數組下標值
    Result := MonthDays[(AMonth = 2) and IsLeapYear(AYear), AMonth];
  end;
  }
  MMOResult.Lines.Add('(DaysInAMonth)年份參數[' + IntToStr(nYear) + ']月份參數[' +
    IntToStr(nMonth) + '],本年度本月份共有:'
    + IntToStr(DaysInAMonth(nYear, nMonth)) + '天');
end;

procedure TFMain.btnTodayClick(Sender: TObject);
begin
  //Today:返回當天日期
  //咱們來看看Today的實現System.DateUtils 第686行
  {
  function Today: TDateTime;
  begin
    //這裏的Date其實也是一個方法,定義在System.SysUtils第18812行
    //內部調用了GetLocalTime這個API,而且使用EncodeDate對返回值進行格式化,只保留日期部分
    Result := Date;
  end;
  }
  MMOResult.Lines.Add('(Today)今日爲:'
    + FormatDateTime('yyyy-MM-dd HH:nn:ss', Today, FDateFormatSetting));
end;

procedure TFMain.btnYesterdayClick(Sender: TObject);
begin
  //Yesterday:返回昨日日期
  //咱們來看看Yesterday的實現System.DateUtils 第691行
  {
  function Yesterday: TDateTime;
  begin
    //這裏實際上是返回了Date-1的一個時間
    //從Today咱們看出Date是調用windowsAPI獲取本機時間,並格式化成日期
    //咱們還知道Delphi中時間的實際上是一個浮點數,整數位是從1899年12月31日到如今的總天數
    //小數位爲一天24小時的百分比
    //因此這裏獲取到今天-1,就是昨天(Date函數返回的是一個日期,不包含時間部分)
    Result := Date - 1;
  end;
  }
  MMOResult.Lines.Add('(Yesterday)昨日爲:'
    + FormatDateTime('yyyy-MM-dd HH:nn:ss', Yesterday, FDateFormatSetting));
end;

procedure TFMain.btnTomorrowClick(Sender: TObject);
begin
  //Tomorrow:返回明日日期
  //咱們來看看Tomorrow的實現System.DateUtils 第696行
  {
  function Tomorrow: TDateTime;
  begin
    //不得不說DELPHI開發團隊很聰明,他們仍是採用的這種當前日期+1的方式來處理的.這裏就不在講解
    Result := Date + 1;
  end;
  }
  MMOResult.Lines.Add('(Tomorrow)明日爲:'
    + FormatDateTime('yyyy-MM-dd HH:nn:ss', Tomorrow, FDateFormatSetting));
end;

procedure TFMain.btnIsTodayClick(Sender: TObject);
var
  dBefore: TDateTime;
begin
  //IsToday:判斷傳入的日期是否爲今天
  dBefore := StrToDateTime(sDate, FDateFormatSetting);
  //咱們來看看IsToday的實現System.DateUtils 第696行
  {
  function IsToday(const AValue: TDateTime): Boolean;
  begin
    //IsSameDay定義在System.DateUtils第706行,判斷參數1是否大於等於參數二,而且小於參數2+1
    //其實在這裏我感受寫這段代碼的人很聰明,最起碼比我聰明,我就沒想到這個處理方式
    //第一個參數是咱們傳入的日期,第二個參數是系統當前日期,注意是日期,不帶時間的日期
    //假現在天是2015-08-13,咱們傳入的是2015-08-13 20:44:28
    //那麼IsSameDay裏面的判斷就是
    //結果=(2015-08-13 20:44:28 >= 2015-08-13 00:00:00) and (2015-08-13 20:44:28 < 2015-08-13 00:00:00 + 1)
    //因此這裏不管我們傳入的是純日期格式,仍是日期+時間格式,都不會出現判斷錯誤問題,很牛
    Result := IsSameDay(AValue, Date);
  end;
  }
  if IsToday(dBefore) then
    MMOResult.Lines.Add('(IsToday)日期參數[' + sDate + '],爲今日')
  else
    MMOResult.Lines.Add('(IsToday)日期參數[' + sDate + '],非今日');
end;

procedure TFMain.btnIsSameDayClick(Sender: TObject);
var
  dBefore, dPar2: TDateTime;
begin
  //IsSameDay:判斷參數1和參數2是不是同一天
  dBefore := StrToDateTime(sDate, FDateFormatSetting);
  dPar2 := dBefore + 1 / 24;
  //咱們來看看IsSameDay的實現System.DateUtils 第706行
  {
  function IsSameDay(const AValue, ABasis: TDateTime): Boolean;
  begin
    //這裏實際上是跟IsToday的判斷差很少
    //Trunc函數爲取得參數的整數部分
    //咱們也知道TDateTime類型的整數部分表明日,因此這裏的判斷相似IsToday
    Result := (AValue >= Trunc(ABasis)) and
              (AValue < Trunc(ABasis) + 1);
  end;
  }
  if IsSameDay(dBefore, dPar2) then
    MMOResult.Lines.Add('(IsSameDay)日期參數1[' + sDate + '],參數2['
      + FormatDateTime('yyyy-MM-dd HH:nn:ss', dPar2, FDateFormatSetting) + '],爲同一天')
  else
    MMOResult.Lines.Add('(IsSameDay)日期參數1[' + sDate + '],參數2['
      + FormatDateTime('yyyy-MM-dd HH:nn:ss', dPar2, FDateFormatSetting) + '],非同一天');
end;
相關文章
相關標籤/搜索