标题: 【练习-028】批处理根据输入的日期格式输出当前日期 [打印本页]
作者: pusofalse 时间: 2008-10-21 18:27 标题: 【练习-028】批处理根据输入的日期格式输出当前日期
出题目的:
综合运用批处理各语句,提高综合运用的水平。
加分规则:
1、思路独特基分5分
2、代码高效基分4分
3、代码简洁基分3分
4、代码通用基分2分
5、无临时文件基分1分
6、完美代码加分15分
题目内容:
根据输入的日期格式输出当天的日期。用y代表年份,m代表月份,d代表当前的日值。
比如今天日期是2008年10月21日:
输入mm dd yyyy,输出10 21 2008
输入yyyy/mm/dd,输出2008/10/21
输入mm-dd/yyyy,输出10-21/2008
输入md-md-yyyy,输出12-01-2008
输入ymydymyd,输出21020081
输入ydmydm-yy,输出221010-08
输入dd---/m/m/ y y y y, 输出21---/1/0/ 2 0 0 8
请先认真发现其中的规律。
相关条件:
1、不同的操作系统,日期格式会有不同。现在的题目中,未知%date%所扩展出的日期的格式,可以是以下的其中一种格式:
星期二 2008-10-21
2008-10-21 星期二
10/21/2008 Tue
Tue 10/21/2008
(只考虑用4位数表示的年份,暂时不必考虑用两位数表示的年份。)
获取当前标准格式的日期的方法不限,不必非要从%date%取值,可以用系统自带的reg.exe读取注册表等方法,只是不能借助第三方工具。
2、日期中各元素之间的连接符只需用/、-或空格,不必考虑用&、|、>等这类的特殊字符。
3、输入的格式中总是有4个y,2个m,2个d,不必考虑格式中只有3个y,1个m,或4个d等不合法的日期格式。而连接符(-、/或空格),可以没有,也可以有1个或多个。-、/、空格可以同时出现。
4、如果是2008-01-01、2000-12-12这样的日期,输入mmddyyyy虽然同ddmmyyyy是一样的结果,都是01012008、12122000,但第一个01确实是月份。ddmmyyyy格式的01012008,第一个01则是当前的日值。一切都以用户输入的为准。输入mdmdyyyy,输出00112008 等。。。
5、用纯批解决。
我的系统是xp_sp2,没有其他的测试环境,只能通过修改代码来测试。还请其他朋友帮忙测试答题人的代码。
[ 本帖最后由 pusofalse 于 2008-10-21 22:56 编辑 ]
作者: terse 时间: 2008-10-21 20:06
不知道%date%所扩展出的日期的格式吗?
如果是 2008-01-01那怎么01是mm还是dd呢
作者: pusofalse 时间: 2008-10-21 20:24
未知%date%的格式。
第一个01当然是mm,第二个当然是dd。
如果是2008-01-01、2000-12-12这样的日期,输入mmddyyyy虽然同ddmmyyyy是一样的结果,都是01012008、12122000,但第一个01确实是月份。ddmmyyyy格式的01012008,第一个01则是当前的日值。
一切都以用户输入的为准。
输入mdmdyyyy,输出00112008 等。。。
[ 本帖最后由 pusofalse 于 2008-10-21 20:59 编辑 ]
作者: 随风 时间: 2008-10-21 20:52
未知%date%的格式。
有可能是 10-21-2008 或 10-21-08 这样的格式吗?
作者: pusofalse 时间: 2008-10-21 21:03 标题: 回复 4楼 的帖子
这样的格式:
星期二 2008-10-21
2008-10-21 星期二
10/21/2008 Tue
Tue 10/21/2008
只考虑用4位数表示年份,暂时不必考虑用两位数表示的年份。
作者: terse 时间: 2008-10-21 21:04
原帖由 pusofalse 于 2008-10-21 20:24 发表
未知%date%的格式。
第一个01当然是mm,第二个当然是dd。
如果是2008-01-01、2000-12-12这样的日期,输入mmddyyyy虽然同ddmmyyyy是一样的结果,都是01012008、12122000,但第一个01确实是月份。ddmmyyyy格式的01 ...
还是有疑惑的
我的意思的 如果 %date%的值是 2008-01-01 那么两个01要自己判断哪个是DD 哪个是MM 是这样吗?
也可以这样说 2008-01-01 第一个01 可以是 dd 也可以是mm 因为各电脑的日期格式不一,所以要代码自己判断了
这样理解对吗
作者: pusofalse 时间: 2008-10-21 21:11 标题: 回复 6楼 的帖子
回复terse前辈,可以这样理解。
但不必非要从%date%中读取日期,也可以用其他的方法,比如读取注册表提取当前日期。。。方法不限,只是不能借助第三方工具。
[ 本帖最后由 pusofalse 于 2008-10-21 21:14 编辑 ]
作者: 随风 时间: 2008-10-21 21:39
看似一个简单的问题,居然也要这么长的代码。。。
:- @echo off&setlocal enabledelayedexpansion
- set /p var=请输入:
- set .y=a&set .m=a&set .d=a&set h=ymd
- for /l %%a in (0 1 9) do set .%%a=a
- for %%i in (%date%) do (
- set str=%%i&set "str=!str:~0,1!"
- if defined .!str! (
- for /f "tokens=1-3 delims=/\,.-: " %%a in ("%%i") do (
- set str=%%a&set str=!str:~2,1!
- if not defined .!str! set h=mdy
- set !h:~0,1!=%%a&set !h:~1,1!=%%b&set "!h:~2,1!=%%c"
- )))
- :loop
- set n=%var:~0,1%
- if defined .%n% (
- set num=!num!!%n%:~0,1!
- set "%n%=!%n%:~1!"
- ) else set "num=%num%%n%"
- set "var=%var:~1%"
- if defined var goto loop
- echo\&echo %num%
- pause>nul
复制代码
[ 本帖最后由 随风 于 2008-10-21 21:43 编辑 ]
作者: pusofalse 时间: 2008-10-21 21:43 标题: 回复 8楼 的帖子
如果%date%是这样的格式就会出错:
10/21/2008 Tue
输入yyyy mm dd,输出10~0,1~ 21 20,本该是2008 10 21。
作者: 随风 时间: 2008-10-21 21:44 标题: 回复 9楼 的帖子
以发现,你再试试?
作者: pusofalse 时间: 2008-10-21 21:53
是的 现在可以了!
不过如果%date%的格式是这样的呢:
月/年/日。 日/年/月。 年/日/月。
。。。而不只是年/月/日 或 月/日/年。
或许也没有这样的日期格式。。。
作者: shqf 时间: 2008-10-21 21:57
- @echo off
- reg export "HKEY_CURRENT_USER\Control Panel\International" 1.reg >nul
- reg add "HKEY_CURRENT_USER\Control Panel\International" /f /v sShortDate /d "yyyy-MM-dd" >nul
-
- :shuchu
- set /p rqgs=请输入日期格式(按q退出):
- if "%rqgs%"=="mm dd yyyy" echo %date:~5,2% %date:~8,2% %date:~0,4%
- if "%rqgs%"=="yyyy/mm/dd" echo %date:~0,4%/%date:~5,2%/%date:~8,2%
- if "%rqgs%"=="mm-dd/yyyy" echo %date:~5,2%-%date:~8,2%/%date:~0,4%
- if "%rqgs%"=="md-md-yyyy" echo %date:~5,1%%date:~8,1%-%date:~6,1%%date:~9,1%-%date:~0,4%
- if "%rqgs%"=="ymydymyd" echo %date:~0,1%%date:~5,1%%date:~1,1%%date:~8,1%%date:~2,1%%date:~6,1%%date:~3,1%%date:~9,1%
- if "%rqgs%"=="ydmydm-yy" echo %date:~0,1%%date:~8,1%%date:~5,1%%date:~1,1%%date:~9,1%%date:~6,1%-%date:~2,1%%date:~3,1%
- if "%rqgs%"=="dd---/m/m/ y y y y" echo %date:~8,2%---/%date:~5,1%/%date:~6,1%/ %date:~0,1% %date:~1,1% %date:~2,1% %date:~3,1%
- echo.
- if /i not "%rqgs%"=="q" goto shuchu
- reg import 1.reg>nul
- echo OK&pause>nul
- exit
复制代码
作者: pusofalse 时间: 2008-10-21 22:02 标题: 回复 12楼 的帖子
回复楼上的兄弟。八个字母的排列方式太多了。
我有可能输入 ym-ym-dydy,抑或m/-yydy/myd。。。
作者: 随风 时间: 2008-10-21 22:03 标题: 回复 11楼 的帖子
那样就无法判断 月和日 了啊?
作者: pusofalse 时间: 2008-10-21 22:13 标题: 回复 14楼 的帖子
是的。%date%的值是日/年/月这样格式的日期我也没见过,只是个人意见而已。不管格式怎样,即使千变万化也能正确输出才能谓之完美。
作者: 随风 时间: 2008-10-21 22:37 标题: 回复 15楼 的帖子
10/2008/10
这样的话,哪个是月哪个是日呢?
这个是必须知道的前提啊?
作者: terse 时间: 2008-10-21 22:45
用个临时文件取日期- @echo off
- set n=-1&set m=+1
- echo wscript.echo date>tmp.vbs
- for /f "tokens=1,2,3* delims=-" %%i in ('cscript /nologo tmp.vbs^&del tmp.vbs') do set "ymda=10%%k 10%%i 10%%j"
- :lp
- echo wscript.echo dateadd("d",%n%,date)>tmp.vbs
- for /f "tokens=1,2,3* delims=-" %%i in ('cscript /nologo tmp.vbs^&del tmp.vbs') do set "ymdb=10%%k 10%%i 10%%j"
- for %%i in (%ymda%) do set %%i=%%i
- for %%i in (%ymdb%) do if %%i gtr 1031 (set yyyy=%%i)else (
- if not defined %%i (set/a dd=%%i%m%,t+=2)else set mm=%%i)
- )
- if %t% gtr 3 set n=+1&set t=&set m=-1&goto lp
- set yyyy=%yyyy:~-4%
- set mm=%mm:~-2%
- set dd=%dd:~-2%
- set .y=%yyyy%
- set .m=%mm%
- set .d=%dd%
- set/p str=请输入:
- setlocal enabledelayedexpansion
- :lp1
- set v=!str:~,1!
- if not defined .%v% (
- if not defined var (set var=!v!)else set var=!var!!v!
- ) else (
- call set var=!var!%%.%v%:~!_%v%!,1%%
- set/a _!v!+=1
- )
- set str=!str:~1!
- if defined str goto lp1
- echo !var!
- pause
复制代码
作者: pusofalse 时间: 2008-10-21 22:49 标题: 回复 16楼 的帖子
sorry,刚刚脑子短路了。。。
因为我的代码是先获取一个yyyymmdd格式的标准格式的日期(所谓标准,即是别的机子上也是如此),所以没有考虑太过关于日/年/月格式该如何区分日、月的问题就说了出来。
依次看来,随风兄的代码算得上完美代码了,期待更多好代码的出现。
作者: pusofalse 时间: 2008-10-21 23:28 标题: 回复 17楼 的帖子
VBS那里能知道个大概意思。lp1标签里的变量嵌套实在太经典了。
出这题的有一部分目的也在于熟悉“变量的嵌套”吧。
作者: terse 时间: 2008-10-21 23:31
这个问题用纯P 有点复杂了
因为毕竟要考虑日期格式的全面性 虽然有的格式并不会出现
就象 我开始问的 2008-01-03 也可以说是一月三号 也可以理解三月一号
我上面的代码 就是取得当天日期的前一天或后一天 有变化的判断为日
判断YYYY的方法是大于4位 余下是年
期待完善版本了
作者: pusofalse 时间: 2008-10-21 23:39 标题: 回复 20楼 的帖子
有变化的判断为日?
特意把日期改为10月1日后再运行,虽然也能正确输出。但“有变化的判断为日”这种说法是否不严谨?因为10月1日前一天是9月30日,月份也变化了。或许是我误解了。
------------------------------------------------------------------
明白了~只看到-1,没看到+1。
[ 本帖最后由 pusofalse 于 2008-10-21 23:49 编辑 ]
作者: 随风 时间: 2008-10-21 23:58
还有个办法就是通过改变系统日期来实现判断 月或日。
作者: terse 时间: 2008-10-22 00:40
恩 可以试 DATE 改
不知道这样行得通否?复制代码
[ 本帖最后由 terse 于 2008-10-22 02:26 编辑 ]
作者: batman 时间: 2008-10-22 12:28
- @echo off&setlocal enabledelayedexpansion
- for %%a in (y1#0#1 y2#1#1 y3#2#1 y4#3#1 m1#5#1 m2#6#1 d1#8#1 d2#9#1) do (
- for /f "tokens=1,2,3 delims=#" %%i in ("%%a") do set "%%i=!date:~%%j,%%k!"
- )
- set /p code=请输入格式:
- :lp
- set "a=!code:~,1!"&set "code=!code:~1!"
- set /a n+=1
- for %%i in (d m y) do (
- if /i "%%i" equ "%a%" set /a .%%i+=1&call,set "_%n%=%%%%i!.%%i!%%"
- )
- if not defined _%n% set "_%n%=%a%"
- if defined code goto lp
- for /l %%i in (1,1,%n%) do set /p=!_%%i!<nul
- pause>nul
复制代码
测试格式为d/m m-y y,d y-y
作者: batman 时间: 2008-10-22 14:15 标题: 再来个通用版(不知道2000能用不)
- @echo off&setlocal enabledelayedexpansion
- set "d=%date%"
- :lp1
- set "a=!d:~,1!"&set "d=!d:~1!"
- for %%i in (0 1 2 3 4 5 6 7 8 9) do if "%%i" equ "%a%" set "str=!str!%a%"&goto next
- :next
- if defined d goto lp1
- set "com=reg query "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate"
- for /f "skip=4 tokens=3" %%i in ('%com%') do set "ymd=%%i"
- set "ymd=%ymd:mm=m%"&set "ymd=!ymd:dd=d!"
- set "ymd=%ymd:m=mm%"&set "ymd=!ymd:d=dd!"
- :lp2
- set "a=!ymd:~,1!"&set "ymd=!ymd:~1!"
- for %%i in (y m d) do (
- if /i "%%i" equ "%a%" (
- set /a .%%i+=1&set "%%i!.%%i!=!str:~,1!"&set "str=!str:~1!"
- )
- )
- if defined ymd goto lp2
- set /p code=请输入格式:
- :lp3
- set "a=!code:~,1!"&set "code=!code:~1!"&set "ok=a"
- for %%i in (y m d) do (
- if /i "%%i" equ "%a%" set /a _%%i+=1&call,set /p=%%%%i!_%%i!%%<nul&set "ok="
- )
- if defined ok set /p=%a%<nul
- if defined code goto lp3
- pause>nul
复制代码
[ 本帖最后由 batman 于 2008-10-22 17:39 编辑 ]
作者: Batcher 时间: 2008-10-22 17:39 标题: 回复 25楼 的帖子
Win2k没有reg.exe
^_^
作者: pusofalse 时间: 2008-10-22 17:41
贴出我的代码,可能存在通用性问题。希望大家测试并指出其中问题:- @echo off&setlocal enabledelayedexpansion
- for /f %%a in ('wmic path win32_operatingsystem get localdatetime') do set "CurrentDate=%%a"
- rem 用wmic获取日期标准格式(yyyymmdd),代码、思路来自于论坛巡查BATCHER。
- rem 标准化获取当前日期:http://www.cn-dos.net/forum/viewthread.php?tid=41857&fpage=1&highlight=%2Bhat
- set "CurrentDate=%CurrentDate:~0,8%"
- set "Format=yyyymmdd"
- for %%a in (Y M D) do set "%%a=defined"
- for %%a in (4 2 2) do call :LOOP %%a
- set /p DateFormat=Input the format:
- :LP
- set "Char=%DateFormat:~,1%"
- if defined !Char! (
- set /a !Char! += 1
- <nul call call set /p=%%%%!Char!%%!Char!%%%%%%
- ) else (
- <nul set /p=!DateFormat:~,1!
- )
- set "DateFormat=!DateFormat:~1!"
- if defined DateFormat goto :LP
- pause>nul &exit /b
-
- :LOOP
- for /l %%a in (1 1 %1) do (
- set "!Format:~,1!%%a=!CurrentDate:~,1!"
- for %%i in (Format CurrentDate) do set "%%i=!%%i:~1!"
- )
复制代码
[ 本帖最后由 pusofalse 于 2008-10-22 17:43 编辑 ]
作者: shqf 时间: 2008-10-22 19:55
先从注册表获得日期格式,把它保存到一个文件,再设置日期格式为yyyy-mm-dd,然后再交由主体程序按输入的格式去输出,最后恢复原先的日期格式。这样可不管原系统是什么日期格式了(3句语句可解决)。这样应该可行吧?可惜 按输入的格式去输出 我理解错了。
[ 本帖最后由 shqf 于 2008-10-22 19:57 编辑 ]
作者: keen 时间: 2009-5-24 01:42
只能显示三种格式:1.用空格隔开的格式,例如mm dd yyyy;2.用/隔开的格式,例如:dd/mm/yyy;3.用-隔开的格式,例如:yyyy-dd-mm- @echo off&setlocal enabledelayedexpansion
- set "str=%date%"
- for /f "delims=0123456789-/" %%i in ("%str%") do set var=!str:%%i=!
- for /f "tokens=1-3 delims=-" %%i in ("%var%") do (
- if "%%j" neq "" (
- set yyyy=%%i&set mm=%%j&set dd=%%k
- ) else (
- for /f "tokens=1-3 delims=/" %%a in ("%var%") do (set mm=%%a&set dd=%%b&set yyyy=%%c)
- )
- )
- set /p input=请输入:
- for /f "tokens=1-3" %%i in ("%input%") do if "%%j" neq "" call,echo %%%%i%% %%%%j%% %%%%k%%
- for /f "tokens=1-3 delims=-" %%i in ("%input%") do if "%%j" neq "" call,echo %%%%i%%-%%%%j%%-%%%%k%%
- for /f "tokens=1-3 delims=/" %%i in ("%input%") do if "%%j" neq "" call,echo %%%%i%%/%%%%j%%/%%%%k%%
- pause>nul
复制代码
作者: netbenton 时间: 2009-5-24 11:53
真的很难!
不过还是做出来了,纯批的,适用多种情况
- @echo off&setlocal enabledelayedexpansion
- set n=1
- for /f "tokens=2 delims=:" %%a in ('echo^;^|date') do (set str!n!=%%a&set/a n+=1)
- set str2=!str2:~2,-2!
- for %%a in (!str1!) do (set var=%%a
- if "!var:-=!" neq "!var!" set fen=-&set str=%%a
- if "!var:/=!" neq "!var!" set fen=/&set str=%%a
-
- )
- set n=3
- for %%a in (!str2:%fen%^= !) do (set str!n!=%%a&set/a n+=1)
- set n=3
- if not defined str4 for %%a in (0 1 2) do (set str!n!=!str2:~%%a,1!&set/a n+=1)
- set n=3
- for %%a in (!str:%fen%^= !) do (
- for %%b in (str!n!) do (
- set !%%b!=%%a&set/a n+=1
- )
- )
-
- for %%a in ("年 月 日" "yyyy mm dd" "yy mm dd") do (
- for /f "tokens=1,2,3" %%b in (%%a) do (
- if defined %%b (
- for /f "tokens=1,2,3" %%e in ("!%%b! !%%c! !%%d!") do (
- endlocal&setlocal enabledelayedexpansion
- set #y=%%e
- set #m=%%f
- set #d=%%g
- ))
- )
- )
-
- :loop
- set in=
- set str=
- set/p in=输入日期格式:
- for %%a in (y m d) do (set in=!in:%%a=" "%%a" "!)
- set/a .y=0,.m=0,.d=0
- for %%a in ("!in!") do (
- if defined #%%~a (
- for %%b in (!.%%~a!) do (
- set str=!str!!#%%~a:~%%b,1!
- )
- set/a .%%~a+=1
- ) else (set str=!str!%%~a)
- )
- echo 分解:"!in!"
- echo 处理结果:!str!
- goto :loop
复制代码
作者: qzwqzw 时间: 2010-1-4 13:54
感觉出题和解题的思路已经过于学究了
研究的目的仍然是应用
而从应用的角度来讨论
各种奇怪的日期格式
其实应该是被抛弃的
而不是被鼓励的
况且题目中出现了任何应用系统都不支持和不会出现的日期格式
那讨论的价值和意义也就失去了
至于练习题的限制条件
我觉得不必强调简洁、高效、无临时文件
也许对于本题不简洁高效的代码和思路
换一个应用环境也许就是唯一适用的
所以思路和创意是最值得鼓励的
从Windows的应用角度来解题的话
这是我的思路
写代码的宗旨是
简单而不必简洁
适用而不必通用
有效而不必高效- @echo off & setlocal
- set/p DateFmt=输入日期格式(MM,yyyy,dd):
- set Regkey="HKEY_CURRENT_USER\Control Panel\International"
- reg export %Regkey% %temp%\~DateFmt.reg > nul
- reg add %Regkey% /v sShortDate /d "%DateFmt%" /f >nul
- echo.%date%
- reg import %temp%\~DateFmt.reg > nul
- for %%f in (%temp%\~DateFmt.reg?) do del %%f
复制代码
作者: neorobin 时间: 2010-1-4 19:53
题目中列出的用户输入格式示例显乱, 题意不好理解, 表达年月日的数字被混插打乱已无实际意义, 偶没了解题欲望
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |