嗨,Scripting Guy!

嗨,Scripting Guy!

歡迎使用 TechNet 專欄,Microsoft Scripting Guys 會在此為您解答有關系統管理指令碼的常見問題。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

今天的問題:如何得知某個日期落在該月的第幾週?


如何得知某個日期落在該月的第幾週?

嗨,Scripting Guy!我要如何得知某個日期落在該月的第幾週?

-- AK

AK,您好。您一定知道《白鯨記》這本書,關於瘋狂的船長一心一意要捕殺大白鯨的故事。這個問題就好比是指令碼界的白鯨記。第一次聽到這個問題時,我們跑去翻閱 VBScript 文件,以為會在其中找到 WeekOfTheMonth 函式。結果沒有:根本就沒有這種函式。然後我們又快速搜尋了新聞群組,還是找不到答案。接下來我們開始絞盡腦汁想找出方法來確定特定日期會落在該月的第幾週。

嗯,還算是絞盡腦汁啦,雖然不是真的做了什麼,只不過三不五時就會想:「天啊,計算一月第幾週的那個問題到底要怎麼解決」。幾天前,我們終於坐下來,想辦法好好解決這個問題。

您猜發生什麼事?我們想出了一個辦法!我們不敢說這是最完美的解決方法,而且我們肯定有其他更好更有效的方法能解決這個問題。但是至少它行得通,這就夠了,不是嗎?(您也知道,像我們這種粗枝大葉的傢伙,一定會說完不完美根本不重要)。

以下指令碼會告訴您,2005 年 12 月 19 日是落在 12 月的第幾週:

dtmTargetDate = #12/19/2005#   

dtmDay = DatePart("d", dtmTargetDate)
dtmMonth = DatePart("m", dtmTargetDate)
dtmYear = DatePart("yyyy", dtmTargetDate)

dtmStartDate = dtmMonth & "/1/" & dtmYear
dtmStartDate = CDate(dtmStartDate)

intWeekday = Weekday(dtmStartDate)
intAddon = 8 - intWeekday

intWeek1 = intAddOn
intWeek2 = intWeek1 + 7
intWeek3 = intWeek2 + 7
intWeek4 = intWeek3 + 7
intWeek5 = intWeek4 + 7
intWeek6 = intWeek5 + 7

If dtmDay <= intWeek6 Then
    strWeek = "Week 6"
End If

If dtmDay <= intWeek5 Then
    strWeek = "Week 5"
End If

If dtmDay <= intWeek4 Then
    strWeek = "Week 4"
End If

If dtmDay <= intWeek3 Then
    strWeek = "Week 3"
End If

If dtmDay <= intWeek2 Then
    strWeek = "Week 2"
End If

If dtmDay <= intWeek1 Then
    strWeek = "Week 1"
End If

Wscript.Echo strWeek

這段指令碼有點複雜,因此我們在這個專欄中只能大致說明其作用;如果想知道鉅細靡遺的內容,您得要自己鑽研。另外我們也假設一個月的第一週表示 1 號所在的那週;至於一個月的第一個完整的週,或是第一個包含工作日的週都跟我們無關。如果想要算出這種週別,也請您自力救濟。

說的夠清楚了。這段指令碼本身假設計算某個日期是落在該月第幾週的關鍵是:確定一個月中第一天是星期幾。原因為何?要是假設第 1 天是星期六,就表示第 2 天是星期日,對我們來說,這表示第 2 天在第 2 週,但是如果第 1 天是星期五呢?此時,第 2 天變成星期六,而對我們來說,這表示第 2 天落在第 1 週。

頭昏了嗎?看一下 2005 年 12 月的月曆。12 月 1、2 和 3 日都落在第 1 週,而 12 月 4 日是第 2 週的第一天:

 

2005 年 12 月

從上圖來看,我們知道「2005 年 12 月 19 日」這個日期落在第 4 週。但是要怎麼使用程式得出這個結果?

一開始我們使用 VBScript 的 DatePart 函式來擷取日期的日 (d)、月 (m) 和年 (yyyy):

dtmDay = DatePart("d", dtmTargetDate)
dtmMonth = DatePart("m", dtmTargetDate)
dtmYear = DatePart("yyyy", dtmTargetDate)

然後使用下列程式碼來建構表示 2005 年 12 月 1 日的新日期:

dtmStartDate = dtmMonth & "/1/" & dtmYear
dtmStartDate = CDate(dtmStartDate)

在第一行我們結合日期字串 – 12/1/2005 – 在第二行則使用 CDate 函式,以確保 VBScript 將字串視為日期時間值。還不賴,對吧?

現在瘋狂的部分來了,我們先是使用 Weekday 函式來確定 12 月 1 日是星期幾:

intWeekday = Weekday(dtmStartDate)

Weekday 會傳回 1 (星期日) 到 7 (星期六) 的整數值。因為 12 月 1 日是星期四,因此會傳回 5。

接著我們要確定第 1 週的最後一天是什麼日期;這點很重要,因為只要知道這個日期,我們就能夠計算每週的最後一個日期。知道這點後,我們就可以算出任何指定日期是在第幾週。 我們使用這段程式碼來確定第 1 週的最後一個日期:

intAddon = 8 - intWeekday

為什麼要使用上述程式碼?問得好。月曆上的 12 月 1 日是星期四,其整數值是 5;8 減 5 等於 3,再看一下月曆:12 月 3 日剛好是第 1 週的最後一天。原來只要用 8 減去星期幾的值,就知道第 1 週最後一天的日期。

耶,我們懂了。試著玩玩看,您就知道這是怎麼運作的了。

既然我們已經知道第 1 週的最後一天是 12 月 3 日,很容易就可以算出每週的最後一個日期;第 2 週最後一天是 12 月 3 日加 7 天,也就是 12 月 10 日。一個月最多可能有六週,我們開始計算六週的最後一天 (姑且不論多數月份都沒有六週):

intWeek1 = intAddOn
intWeek2 = intWeek1 + 7
intWeek3 = intWeek2 + 7
intWeek4 = intWeek3 + 7
intWeek5 = intWeek4 + 7
intWeek6 = intWeek5 + 7

接下來的部分我們可以寫幾行程式碼來完成,但是我們希望能更清楚解釋這項作業,因此我們使用一連串的 If-Then 陳述式來結合程式碼。我們已經確定目標日期的日子部分:19。我們也已經確定一個月中每週的最後一個日期:

 

最後日期
638
531
423
317
210
13

下一步便是檢查這天 – 19 – 小於或等於各週最後一天的日期。19 小於第 6 週的最後日期 38 嗎?是的,因此我們將變數值 strWeek 設為「Week 6」。那它小於第 5 週的最後日期 31 嗎?是的,因此我們現在將 strWeek 值設為「Week 5」。那第 4 週呢?是的,因此 strWeek 現在等於「Week 4」。有道理嗎?

那麼,第 3 週呢?19 小於或等於 17 嗎?不是,因此我們不變更 strWeek 的值,就不管它。完成最後一個 If-Then 陳述式後,我們回應結果:結果發現 2005 年 12 月 19 日落在當月的第 4 週。

很抱歉,我們只能為這個稍微複雜的指令碼提供粗略的說明,有效最重要。雖然指令碼看起來很怪,但是總比追殺大白鯨容易多了 (雖然我們很投入,但還是設法採取最簡單的方法)。


如需詳細資訊

查看嗨,Scripting Guy!- 過往文件

 

回到頁首 回到頁首