elexy 发表于 2020-3-27 12:32:04

[已解决]求上一个工作日,不考虑特殊节假日

本帖最后由 elexy 于 2020-3-27 13:16 编辑

#include <Date.au3>

;有以下【周一到周五 工作日】的几种情况,可有什么函数能实现 [求上一个工作日,不用考虑特殊节假日]?请大神们赐教

$day = 20200327 ;一般
MsgBox(64, '上一个工作日', '20200326')

$day = 20200323 ;跨周末
MsgBox(64, '上一个工作日', '20200320')

$day = 20200302 ;跨月
MsgBox(64, '上一个工作日', '20200228')

$day = 20200101 ;跨年
MsgBox(64, '上一个工作日', '20191231')

afan 发表于 2020-3-27 13:00:02

#include <Date.au3>
$day = 20200327 ;一般
MsgBox(64, $day & ' 上一个工作日', _LastWorkDay($day));'20200326')
$day = 20200323 ;跨周末
MsgBox(64, $day & ' 上一个工作日', _LastWorkDay($day));'20200320')
$day = 20200302 ;跨月
MsgBox(64, $day & ' 上一个工作日', _LastWorkDay($day));'20200228')
$day = 20200101 ;跨年
MsgBox(64, $day & ' 上一个工作日', _LastWorkDay($day));'20201231')

Func _LastWorkDay($sNowDay)
        If Not StringInStr($sNowDay, '/') Then $sNowDay = StringRegExpReplace($sNowDay, '(?<=^\d{4})(\d{2})(?=\d\d$)', '/${1}/')
        Local $sNewDate, $aDate, $iWeekday, $step = 0
        Do
                $step -= 1
                $sNewDate = _DateAdd('D', $step, $sNowDay)
                $aDate = StringRegExp($sNewDate, '^(\d{4})\D(\d\d)\D(\d\d)', 1)
                If @error Then Return SetError(1)
                $iWeekday = _DateToDayOfWeek($aDate, $aDate, $aDate)
        Until $iWeekday > 1 And $iWeekday < 7
        Return $sNewDate
EndFunc   ;==>_LastWorkDay

zghwelcome 发表于 2020-3-27 13:12:30

A版迅速


#include <date.au3>

Local $day = '20200101'
Local $sGetDay = _GetDay($day)
If Not @error Then MsgBox(0,0,$sGetDay)


Func _GetDay($day)
        Local $aReg = StringRegExp($day, '(\d{4})(\d\d)(\d\d)', 1)
        If @error Then Return SetError(1, 0, '')
        For $i = 1 To 3
                Local $sRet = _DateAdd('D', -$i, $aReg & '/' & $aReg & '/' & $aReg)
                If @error Then         ContinueLoop
                Local $aRet = StringRegExp($sRet, '\d+', 3)
                If @error Then         ContinueLoop
                Local $sWeekDay = _DateToDayOfWeek($aRet, $aRet, $aRet)
                If $sWeekDay > 1 And $sWeekDay < 7 Then Return $aRet & $aRet & $aRet
        Next
        Return SetError(2, 0, '')
EndFunc   ;==>_GetDay


elexy 发表于 2020-3-27 13:17:22

历害历害,够我好好琢磨一会了

yidianyudi 发表于 2020-3-30 22:59:57

厉害了,仔细看下

chzj589 发表于 2020-4-1 19:02:22

afan 发表于 2020-3-27 13:00


今天查询上周最后工作日就不准了
$day = 20200401 ;跨周末
MsgBox(64, $day & ' 上一个工作日', _LastWorkDay($day));'20200401')

afan 发表于 2020-4-1 19:07:26

chzj589 发表于 2020-4-1 19:02
今天查询上周最后工作日就不准了
$day = 20200401 ;跨周末
MsgBox(64, $day & ' 上一个工作日', _LastW ...

20200401 它的上一个工作日就是20200331(同周的周二),没有跨周末哦~

chzj589 发表于 2020-4-1 19:41:17

afan 发表于 2020-4-1 19:07
20200401 它的上一个工作日就是20200331(同周的周二),没有跨周末哦~

$day = 20200401 ;跨周末
MsgBox(64, $day & ' 上周', ' 上周最后一个工作日'&_LastWorkDay($day))
不好意思,没说清楚

afan 发表于 2020-4-1 19:47:28

chzj589 发表于 2020-4-1 19:41
$day = 20200401 ;跨周末
MsgBox(64, $day & ' 上周', ' 上周最后一个工作日'&_LastWorkDay($day))
不 ...

上周最后一个工作日?那肯定不能用“上一个工作日”的解法。
先 _DateToDayOfWeek()得到星期号,再_DateAdd(-该星期号-2天)

afan 发表于 2020-4-1 19:59:33

chzj589 发表于 2020-4-1 19:41
$day = 20200401 ;跨周末
MsgBox(64, $day & ' 上周', ' 上周最后一个工作日'&_LastWorkDay($day))
不 ...

$day = 20200401 ;
MsgBox(64, $day & ' 上周最后一个工作日(周五)', _LastWeekFriday($day));'2020327')

Func _LastWeekFriday($sNowDay)
        If Not StringInStr($sNowDay, '/') Then $sNowDay = StringRegExpReplace($sNowDay, '(?<=^\d{4})(\d{2})(?=\d\d$)', '/${1}/')
        Local $aDate = StringRegExp($sNowDay, '^(\d{4})\D(\d\d)\D(\d\d)', 1)
        Local $iWeekday = _DateToDayOfWeek($aDate, $aDate, $aDate)
        Return _DateAdd('D', -$iWeekday - 1, $sNowDay)
EndFunc   ;==>_LastWeekFriday

chzj589 发表于 2020-4-1 20:01:07

afan 发表于 2020-4-1 19:47
上周最后一个工作日?那肯定不能用“上一个工作日”的解法。
先 _DateToDayOfWeek()得到星期号,再_Date ...

是跨月的原因,如是本月就可行
$day = 20200330 ;跨周末
MsgBox(64, $day & ' 上周', ' 上周最后一个工作日'&_LastWorkDay($day))
结果:20200327

afan 发表于 2020-4-1 21:48:15

chzj589 发表于 2020-4-1 20:01
是跨月的原因,如是本月就可行
$day = 20200330 ;跨周末
MsgBox(64, $day & ' 上周', ' 上周最后一个 ...

显然不是,跟跨月没关系。
只有周一可以套得上,因为它的上一个工作日就是你所要的上周最后一个工作日。
就像一停走的挂钟一天中也有两次时间是对的……
页: [1]
查看完整版本: [已解决]求上一个工作日,不考虑特殊节假日