如何生成连续的日期? (添加 N 天到现在)
How to generate succesive dates? (add N days to date)
我正在编写一个简单的批处理脚本,允许用户输入开始日期和结束日期,然后它会传输名称中包含日期的文件。它需要像“20220215”这样的年月日。例如,用户输入“20211110”,然后输入“20211215”,它会抓取从 2021 年 11 月 11 日到 2021 年 12 月 15 日的文件。我试图从输入字符串中抓取日期和月份,但问题是值“08” ' 和 '09' 会因为十六进制值等原因给脚本带来麻烦。所以我为文件日做案例,因为它在字符串的末尾,所以工作正常。问题是月份。这是代码:
REM Works fine
IF !temp_var:~6! == 08 (
SET /A file_day = 8
) ELSE IF !temp_var:~6! == 09 (
SET /A file_day = 9
) ELSE (
SET /A file_day = !temp_var:~6!
)
REM Crashes script
IF !temp_var:~4, -2! == 08 (
SET /A file_month = 8
) ELSE IF !temp_var:~4, -2! == 09 (
SET /A file_month = 9
) ELSE (
SET /A file_month = !temp_var:~4, -2!
我在 运行 脚本时收到的错误是
-2 was unexpected at this time.
我发现它只是在月份块的第一个 IF 语句中。但是每次我搜索如何从变量中获取数字时,它都使用 %var:~#:#% 格式。
我已经考虑切换到另一种语言或方法来执行此操作,但我认为我尝试自动化的任务很简单,可以通过将批处理 运行 几个命令哈哈来实现。
感谢您的帮助!
此程序生成一系列连续日期:
@echo off
setlocal
echo Date format: YYYYMMDD
set /P "startDate=Enter start date: "
set /P "endDate=Enter end date: "
echo/
echo %startDate%
set /A "YYYY=%startDate:~0,4%, m=1%startDate:~4,2%-100, d=1%startDate:~6%-100"
:nextDate
set /A "d+=1, nextMon=!(d-(31+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4)))), d=d*!nextMon+nextMon, m+=nextMon, nextYear=!(m-13), m=m*!nextYear+nextYear, YYYY+=nextYear, MM=100+m, DD=100+d"
set "nextDate=%YYYY%%MM:~1%%DD:~1%
echo %nextDate%
if %nextDate% neq %endDate% goto nextDate
这是对所用方法的描述:
d+=1
是第二天。
30+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4))
是每个月对应的天数:
1=31、2=28 或 29、3=31、4=30、5=31、6=30、7=31、8=31、9=30、10=31、11=30和 12=31.
也就是说,从 1 到 7 的奇数月份获得 30 + 1(否则为 30+0),并在 7 之后的偶数月份切换为 30 + 1(否则为 30+0),并额外调整( 2 月份的结果为 -2 或 -1)。为了得到这样的结果,我们使用了这些部分:
(m+m/8)
对于 M<8 是 M,否则是 M+1。 ((m+m/8)&1)
是我们在月 <> 2 中添加到 30 的 1 或 0。
(m-2)
对于 M==2 为 0,否则为 <>0,因此 !(m-2)
对于 M==2 为 1,否则为 0,而 !(m-2)*2
是我们的 2当 M==2 时,30 减去 28。当年份可以被 4 整除时 YYYY%%4
为 0,否则为 <>0,因此当年份为闰年时 !(YYYY%%4)
是对 1 的调整(我们从得出 28 的 2 开始调整)(所以在闰年二月给出 29).
最后,我们 assemble 所有这些部分并得到: 30+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4))
这是所有月份和所有年份的每月天数。将 30
更改为 31
给出 DaysPerMonthPlusOne 的数量。
技术提示:此公式不符合被 400 整除的年份 不是 闰年的规则(如 2000),因此该方法将失败在2400年。为了修正这一点,我们需要在年份被400整除时取消调整1,即:31+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4)+!(YYYY%%400))
d-(DaysPerMonthPlusOne)
当第二天超过当月的天数时为0,所以nextMon=!(d-(DaysPerMonthPlusOne))
当月份改变时为1,否则为0。
d=d*!nextMon+nextMon
当月份没有变化时是相同的 D 值,否则为 1(nextMon 的值)。
m+=nextMon
当月份改变时递增 M。
m-13
当 M 超过年份时为 0,所以当年份改变时 nextYear=!(m-13)
为 1(否则为 0)。
m=m*!nextYear+nextYear
年份不变时为相同的 M 值,否则为 1(下一年的值)。
YYYY+=nextYear
当年份改变时递增 YYYY。
最后MM=100+m, DD=100+d
是3位数的变量(如m为3时的103),分别用两位数表示月份和日期。
参考:这个方法是我自己开发的...;)
EDIT 2022/03/23:添加几天的修改
我修改了这个程序以增加几天(超过一天)。只要天数的增量不跳到超过一个月,该方法就可以正常工作。尽管可以很容易地修改该方法以适用于任意天数,但无法在单个算术表达式中实现修改...
@echo off
setlocal
echo Date format: YYYYMMDD
set /P "startDate=Enter start date: "
set /P "endDate=Enter end date: "
set /P "numDays=Enter days increment: "
echo/
echo %startDate%
set /A "YYYY=%startDate:~0,4%, m=1%startDate:~4,2%-100, d=1%startDate:~6%-100"
:nextDate
set /A "d+=numDays, DPM=30+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4)), nextMon=((d-1-DPM)>>31)+1, d-=nextMon*DPM, m+=nextMon, nextYear=!(m-13), m=m*!nextYear+nextYear, YYYY+=nextYear, MM=100+m, DD=100+d"
set "nextDate=%YYYY%%MM:~1%%DD:~1%
echo %nextDate%
if %nextDate% lss %endDate% goto nextDate
这些是新方法中更改的详细信息:
(d-1-DPM)
当日期小于或等于 DaysPerMonth 时为 负数 否则为 0 或正数,因此 ((d-1-DPM)>>31)
(这样的结果右移 31 位)当日期在同一月份时为 -1,否则为 0,因此 nextMon=((d-1-DPM)>>31)+1
当月份发生变化时为 1,否则为 0。
d-=nextMon*DPM
当某天属于下个月时减去当月的天数
我正在编写一个简单的批处理脚本,允许用户输入开始日期和结束日期,然后它会传输名称中包含日期的文件。它需要像“20220215”这样的年月日。例如,用户输入“20211110”,然后输入“20211215”,它会抓取从 2021 年 11 月 11 日到 2021 年 12 月 15 日的文件。我试图从输入字符串中抓取日期和月份,但问题是值“08” ' 和 '09' 会因为十六进制值等原因给脚本带来麻烦。所以我为文件日做案例,因为它在字符串的末尾,所以工作正常。问题是月份。这是代码:
REM Works fine
IF !temp_var:~6! == 08 (
SET /A file_day = 8
) ELSE IF !temp_var:~6! == 09 (
SET /A file_day = 9
) ELSE (
SET /A file_day = !temp_var:~6!
)
REM Crashes script
IF !temp_var:~4, -2! == 08 (
SET /A file_month = 8
) ELSE IF !temp_var:~4, -2! == 09 (
SET /A file_month = 9
) ELSE (
SET /A file_month = !temp_var:~4, -2!
我在 运行 脚本时收到的错误是
-2 was unexpected at this time.
我发现它只是在月份块的第一个 IF 语句中。但是每次我搜索如何从变量中获取数字时,它都使用 %var:~#:#% 格式。
我已经考虑切换到另一种语言或方法来执行此操作,但我认为我尝试自动化的任务很简单,可以通过将批处理 运行 几个命令哈哈来实现。
感谢您的帮助!
此程序生成一系列连续日期:
@echo off
setlocal
echo Date format: YYYYMMDD
set /P "startDate=Enter start date: "
set /P "endDate=Enter end date: "
echo/
echo %startDate%
set /A "YYYY=%startDate:~0,4%, m=1%startDate:~4,2%-100, d=1%startDate:~6%-100"
:nextDate
set /A "d+=1, nextMon=!(d-(31+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4)))), d=d*!nextMon+nextMon, m+=nextMon, nextYear=!(m-13), m=m*!nextYear+nextYear, YYYY+=nextYear, MM=100+m, DD=100+d"
set "nextDate=%YYYY%%MM:~1%%DD:~1%
echo %nextDate%
if %nextDate% neq %endDate% goto nextDate
这是对所用方法的描述:
d+=1
是第二天。30+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4))
是每个月对应的天数:
1=31、2=28 或 29、3=31、4=30、5=31、6=30、7=31、8=31、9=30、10=31、11=30和 12=31.
也就是说,从 1 到 7 的奇数月份获得 30 + 1(否则为 30+0),并在 7 之后的偶数月份切换为 30 + 1(否则为 30+0),并额外调整( 2 月份的结果为 -2 或 -1)。为了得到这样的结果,我们使用了这些部分:
(m+m/8)
对于 M<8 是 M,否则是 M+1。 ((m+m/8)&1)
是我们在月 <> 2 中添加到 30 的 1 或 0。
(m-2)
对于 M==2 为 0,否则为 <>0,因此 !(m-2)
对于 M==2 为 1,否则为 0,而 !(m-2)*2
是我们的 2当 M==2 时,30 减去 28。当年份可以被 4 整除时 YYYY%%4
为 0,否则为 <>0,因此当年份为闰年时 !(YYYY%%4)
是对 1 的调整(我们从得出 28 的 2 开始调整)(所以在闰年二月给出 29).
最后,我们 assemble 所有这些部分并得到: 30+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4))
这是所有月份和所有年份的每月天数。将 30
更改为 31
给出 DaysPerMonthPlusOne 的数量。
技术提示:此公式不符合被 400 整除的年份 不是 闰年的规则(如 2000),因此该方法将失败在2400年。为了修正这一点,我们需要在年份被400整除时取消调整1,即:31+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4)+!(YYYY%%400))
d-(DaysPerMonthPlusOne)
当第二天超过当月的天数时为0,所以nextMon=!(d-(DaysPerMonthPlusOne))
当月份改变时为1,否则为0。d=d*!nextMon+nextMon
当月份没有变化时是相同的 D 值,否则为 1(nextMon 的值)。m+=nextMon
当月份改变时递增 M。m-13
当 M 超过年份时为 0,所以当年份改变时nextYear=!(m-13)
为 1(否则为 0)。m=m*!nextYear+nextYear
年份不变时为相同的 M 值,否则为 1(下一年的值)。YYYY+=nextYear
当年份改变时递增 YYYY。最后
MM=100+m, DD=100+d
是3位数的变量(如m为3时的103),分别用两位数表示月份和日期。
参考:这个方法是我自己开发的...;)
EDIT 2022/03/23:添加几天的修改
我修改了这个程序以增加几天(超过一天)。只要天数的增量不跳到超过一个月,该方法就可以正常工作。尽管可以很容易地修改该方法以适用于任意天数,但无法在单个算术表达式中实现修改...
@echo off
setlocal
echo Date format: YYYYMMDD
set /P "startDate=Enter start date: "
set /P "endDate=Enter end date: "
set /P "numDays=Enter days increment: "
echo/
echo %startDate%
set /A "YYYY=%startDate:~0,4%, m=1%startDate:~4,2%-100, d=1%startDate:~6%-100"
:nextDate
set /A "d+=numDays, DPM=30+((m+m/8)&1)-!(m-2)*(2-!(YYYY%%4)), nextMon=((d-1-DPM)>>31)+1, d-=nextMon*DPM, m+=nextMon, nextYear=!(m-13), m=m*!nextYear+nextYear, YYYY+=nextYear, MM=100+m, DD=100+d"
set "nextDate=%YYYY%%MM:~1%%DD:~1%
echo %nextDate%
if %nextDate% lss %endDate% goto nextDate
这些是新方法中更改的详细信息:
(d-1-DPM)
当日期小于或等于 DaysPerMonth 时为 负数 否则为 0 或正数,因此((d-1-DPM)>>31)
(这样的结果右移 31 位)当日期在同一月份时为 -1,否则为 0,因此nextMon=((d-1-DPM)>>31)+1
当月份发生变化时为 1,否则为 0。d-=nextMon*DPM
当某天属于下个月时减去当月的天数