找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 70516|回复: 19

[数值计算] [已解决]批处理转换秒数格式出错,求助 看看哪里的问题?

[复制链接]
发表于 2024-3-5 15:27:51 | 显示全部楼层 |阅读模式
本帖最后由 hnfeng 于 2024-3-7 08:35 编辑

想写个“秒数”转换为“hh:mm:ss” 格式的时间的函数,但是运行时显示“此时不应有 else”,不知道哪里的问题,请高手看看:
  1. ::@echo off
  2. setlocal EnableDelayedExpansion&cd /d "%~dp0"&title %~nx0 &color 07

  3. call :Sec2Time 8 hhmmss
  4. echo 8 %hhmmss%
  5. pause

  6. call :Sec2Time 68 hhmmss
  7. echo 68 %hhmmss%
  8. pause

  9. call :Sec2Time 168 hhmmss
  10. echo 168 %hhmmss%
  11. pause

  12. call :Sec2Time 3668 hhmmss
  13. echo 3668 %hhmmss%
  14. pause

  15. call :Sec2Time 13668 hhmmss
  16. echo 13668 %hhmmss%
  17. pause

  18. exit /b


  19. ::==================================
  20. :Sec2Time
  21. setlocal ENABLEEXTENSIONS
  22. set hh=0
  23. set mm=0
  24. set ss=0
  25. if %1 LSS 60 (
  26.   endlocal & set %2=!hh!:!mm!:%1
  27.   ) else (
  28.     if %1 LSS 3600 (
  29.     set /a mm=%1 / 60
  30.     set /a ss=$1 - (!mm! * 60)
  31.     endlocal & set %2=!hh!:!mm!:!ss!
  32.     ) else (
  33.       set /a hh=%1 / 3600
  34.       set /a mm=(%1 - (!hh! * 3600)) / 60
  35.       set /a ss=%1 - !hh! * 3600 - !mm! * 60
  36.       endlocal & set %2=!hh!:!mm!:!ss!
  37.   )
  38. )
  39. goto :EOF
复制代码
发表于 2024-3-5 15:50:27 | 显示全部楼层
  1. if %1 LSS 60 (
  2.         endlocal & set %2=!hh!:!mm!:%1
  3. ) else (
  4.         if %1 LSS 3600 (
  5.                 set /a mm=%1 / 60
  6.                 set /a ss=$1 - ^(!mm! * 60^)
  7.                 endlocal & set %2=!hh!:!mm!:!ss!
  8.         ) else (
  9.                 set /a hh=%1 / 3600
  10.                 set /a mm=^(%1 - ^(!hh! * 3600^)^) / 60
  11.                 set /a ss=%1 - !hh! * 3600 - !mm! * 60
  12.                 endlocal & set %2=!hh!:!mm!:!ss!
  13.         )
  14. )
复制代码
 楼主| 发表于 2024-3-5 16:24:38 | 显示全部楼层
回复 2# 77七


    厉害,一下子就看到问题了,多谢多谢

可能还有其他问题, 第一个运行结果正确,其他的输出结果不正确, 不知哪里的问题:
  1. 8 0:0:8
  2. 请按任意键继续. . .
  3. 68 0:0:0
  4. 请按任意键继续. . .
  5. 168 0:0:0
  6. 请按任意键继续. . .
  7. 3668 0:0:0
  8. 请按任意键继续. . .
  9. 13668 0:0:0
  10. 请按任意键继续. . .
复制代码
发表于 2024-3-5 16:34:57 | 显示全部楼层
回复 1# hnfeng


    前面开了延时,跳转出就不要取消,不然你设置了时分秒都不会变了。
另外set /a 作为计算运算时,特殊符号要记得用转义符。
添加双零,在只有分秒的时候美观一些。
  1. :Sec2Time

  2. set hh=00
  3. set mm=00
  4. set ss=00
  5. if %1 LSS 60 (
  6.         set %2=!hh!:!mm!:%1
  7.   ) else (
  8.           if %1 LSS 3600 (
  9.         set /a mm=%1 / 60
  10.         set /a ss=%1 - ^(!mm! * 60^)
  11.         set %2=!hh!:!mm!:!ss!
  12.         ) else (
  13.       set /a hh=%1 / 3600
  14.       set /a mm=^(%1 - ^(!hh! * 3600^)^) / 60
  15.       set /a ss=%1 - !hh! * 3600 - !mm! * 60
  16.       set %2=!hh!:!mm!:!ss!
  17.   )
  18. )
  19. goto :EOF
复制代码
发表于 2024-3-5 16:36:08 | 显示全部楼层
回复 3# hnfeng


    你原来的代码,38行,输错了一个$
 楼主| 发表于 2024-3-5 16:48:42 | 显示全部楼层
回复 5# ppll2030


    是的是的,这个失误不应该
 楼主| 发表于 2024-3-5 16:49:58 | 显示全部楼层
多谢前面两位帮忙,计算没问题了。我再试试把 1位 的前面添加 0
 楼主| 发表于 2024-3-5 17:16:16 | 显示全部楼层
本帖最后由 hnfeng 于 2024-3-5 17:40 编辑

初步可以了,但是因为想在 批处理面使用延迟变量,又不想 函数 里面的变量与从主代码里面的变量冲突,有没有办法呢?
  1. @echo off&setlocal EnableDelayedExpansion&cd /d "%~dp0"&title %~nx0 &color 07

  2. call :Sec2Time 8 hhmmss
  3. echo 8        %hhmmss%

  4. call :Sec2Time 68 hhmmss
  5. echo 68        %hhmmss%

  6. call :Sec2Time 168 hhmmss
  7. echo 168        %hhmmss%

  8. call :Sec2Time 3668 hhmmss
  9. echo 3668        %hhmmss%

  10. call :Sec2Time 13668 hhmmss
  11. echo 13668        %hhmmss%

  12. call :Sec2Time 83668 hhmmss
  13. echo 83668        %hhmmss%

  14. echo;&pause
  15. exit /b


  16. ::==================================
  17. :Sec2Time
  18. set hh=00
  19. set mm=00
  20. set ss=00
  21. if %1 LSS 60 (
  22.   set ss=0%1
  23.         set %2=!hh!:!mm!:!ss:~-2!
  24. ) else (
  25.         if %1 LSS 3600 (
  26.         set /a mm=%1 / 60
  27.         set /a ss=%1 - ^(!mm! * 60^)
  28.         set mm=0!mm!
  29.         set ss=0!ss!
  30.         set %2=!hh!:!mm:~-2!:!ss:~-2!
  31.         ) else (
  32.     set /a hh=%1 / 3600
  33.     set /a mm=^(%1 - ^(!hh! * 3600^)^) / 60
  34.     set /a ss=%1 - !hh! * 3600 - !mm! * 60
  35.         if !hh! LSS 10 set hh=0!hh!
  36.     set mm=0!mm!
  37.     set ss=0!ss!
  38.     set %2=!hh!:!mm:~-2!:!ss:~-2!
  39.   )
  40. )
  41. goto :EOF

复制代码
  1. 8       00:00:08
  2. 68      00:01:08
  3. 168     00:02:48
  4. 3668    01:01:08
  5. 13668   03:47:48
  6. 83668   23:14:28

  7. 请按任意键继续. . .
复制代码
发表于 2024-3-5 17:21:44 | 显示全部楼层
可以用for /f把变量带出来
  1. :Sec2Time
  2. setlocal enabledelayedexpansion
  3. set hh=0
  4. set mm=0
  5. set ss=0
  6. if %1 LSS 60 (
  7.         endlocal & set %2=%hh%:%mm%:%1
  8. ) else if %1 LSS 3600 (
  9.         set /a mm=%1 / 60
  10.         set /a "ss=%1 - (mm * 60)"
  11.         for /f "tokens=1-2" %%a in ("!mm! !ss!") do (
  12.                 endlocal
  13.                 set %2=%hh%:%%a:%%b
  14.         )
  15. )
  16. goto :EOF
复制代码


也可以简单点
  1. set /a hh=%1/3600,mm=%1/60%%60,ss=%1%%60
复制代码



set /a 自带变量延迟扩展特性,不需要用!!包裹变量,这里如果将两个set /a 写成一行,set /a mm=%1/60,ss=%1-(!mm!*60),容易出错。crlf大佬的教程 [分享]Crlf 的拙作与收集的教程 提到了这点。
发表于 2024-3-5 17:53:32 | 显示全部楼层
回复 8# hnfeng


  
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. call :Sec2Time 3668 hhmmss
  4. echo %hhmmss%
  5. pause
  6. exit /b

  7. :Sec2Time
  8. setlocal
  9. set /a hh=%1/3600+100,mm=%1/60%%60+100,ss=%1%%60+100
  10. endlocal & set %2=%hh:~-2%:%mm:~-2%:%ss:~-2%
  11. exit /b
复制代码
发表于 2024-3-5 18:18:42 | 显示全部楼层
本帖最后由 aloha20200628 于 2024-3-5 18:20 编辑

回复 8# hnfeng

一楼的代码除了明显的几个错误如 ENABLEEXTENSIONS,$1,...已被指出外,真正致命的是如下两个错误》
一。在用括号包裹的if语块内,set/a 句式若含括号,须用双引号包裹,例如 set/a "v=5-(100/2)";
二。局部变量续命给全局变量的句式 endlocal & set %2=!v! 字面量应为 endlocal & set %2=%v% 但更关键的是该句式不能在复合语块(如if或for)内使用(建议用法见订正代码)
如下代码是订正后的示例代码(主要针对子过程部分),已测试通过

  1. @echo off
  2. call :Sec2Time 13668 hhmmss
  3. echo 13668 %hhmmss%
  4. exit /b

  5. :Sec2Time
  6. setlocal enabledelayedexpansion
  7. set hh=0
  8. set mm=0
  9. set ss=0
  10. if %1 LSS 60 (
  11.         set v=!hh!:!mm!:%1
  12. ) else (
  13.         if %1 LSS 3600 (
  14.         set /a mm=%1/60
  15.         set /a ss=%1-!mm!*60
  16.         set v=!hh!:!mm!:!ss!
  17.         ) else (
  18.           set /a hh = %1 / 3600
  19.           REM 关键点之一如下
  20.           set /a "mm=(%1-!hh!*3600)/60"
  21.           set /a ss=%1-!hh!*3600-!mm!*60
  22.           set v=!hh!:!mm!:!ss!
  23.   )
  24. )
  25. REM 关键点之二如下
  26. endlocal & set %2=%v%
  27. exit/b
复制代码
 楼主| 发表于 2024-3-5 20:37:56 | 显示全部楼层
可以用for /f把变量带出来

也可以简单点



set /a 自带变量延迟扩展特性,不需要用!!包裹变量,这里 ...
77七 发表于 2024-3-5 17:21



    能否讲讲 mm=%1/60%%60 和 ss=%1%%60 中的 %%60 是什么意思?看不懂
 楼主| 发表于 2024-3-5 20:38:34 | 显示全部楼层
回复  hnfeng
77七 发表于 2024-3-5 17:53



    太精练了,多谢多谢
 楼主| 发表于 2024-3-5 20:38:54 | 显示全部楼层
回复  hnfeng

一楼的代码除了明显的几个错误如 ENABLEEXTENSIONS,$1,...已被指出外,真正致命的是如下 ...
aloha20200628 发表于 2024-3-5 18:18



    学习了,多谢指教
发表于 2024-3-5 21:30:08 | 显示全部楼层
回复 12# hnfeng


   算除以60的余数
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-18 04:23 , Processed in 0.074006 second(s), 7 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表