programing

Windows 배치: 날짜를 변수로 포맷

subpage 2023. 4. 9. 21:30
반응형

Windows 배치: 날짜를 변수로 포맷

현재 날짜를 YYY-MM-DD 형식으로 Windows .bat 파일의 변수에 저장하려면 어떻게 해야 합니까?

UNIX 쉘 아날로그:

today=`date +%F`
echo $today

로케일에 구애받지 않는 방법으로 현재 날짜를 가져올 수 있습니다.

for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x

그런 다음 서브스트링을 사용하여 개별 부품을 추출할 수 있습니다.

set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%

개별 부품을 포함하는 변수를 얻는 또 다른 방법은 다음과 같습니다.

for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%

가변 네임스페이스를 오염시키는 대신 서브스트링을 만지작거리는 것보다 훨씬 낫습니다.

현지시간 대신 UTC가 필요한 경우 명령어는 거의 동일합니다.

for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%

date /T이치노

이 " " " 인 Thu 17/03/2016다음과 같이 합니다.

set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2%
echo %datestr%

배치 파일의 표준 MS-DOS 명령을 사용하여 이를 수행하려면 다음을 사용합니다.

FOR /F "TOKENS=1 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET dd=%%A
FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B
FOR /F "TOKENS=1,2,3 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET yyyy=%%C

더 개선할 수 있다고 생각합니다만, Day(dd), Month(mm), Year(yyy)의 3개의 변수로 날짜를 지정할 수 있습니다.그런 다음 필요에 따라 나중에 배치 스크립트에서 이러한 항목을 사용할 수 있습니다.

SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%

이 질문에 대한 답변이 받아들여진 것은 이해하지만, WMI 콘솔을 사용하지 않고 이를 실현하고자 하는 많은 사람들이 이 대체 방법을 선호할 수 있기 때문에 이 질문에 어떤 가치를 부여하기를 바랍니다.

시간 설정에 의존하지 않는 다른 두 가지 방법(둘 다 현지화에서 데이터/시간을 얻는 방법에서 사용)또한 둘 다 요일이 부여되어 관리자 권한이 필요하지 않습니다.

  1. MAKECAB - 모든 Windows 시스템에서 동작합니다(빠르지만 작은 임시 파일을 만듭니다)(foxidrive 스크립트):

    @echo off
    pushd "%temp%"
    makecab /D RptFileName=~.rpt /D InfFileName=~.inf /f nul >nul
    for /f "tokens=3-7" %%a in ('find /i "makecab"^<~.rpt') do (
        set "current-date=%%e-%%b-%%c"
        set "current-time=%%d"
        set "weekday=%%a"
    )
    del ~.*
    popd
    echo %weekday% %current-date% %current-time%
    pause
    
  2. ROBOCOPY - Windows XP 및 Windows Server 2003의 네이티브 명령어는 아니지만 Microsoft 사이트에서 다운로드할 수 있습니다.다만, Windows Vista 이후의 모든 것에 짜넣어져 있습니다.

    @echo off
    setlocal
    for /f "skip=8 tokens=2,3,4,5,6,7,8 delims=: " %%D in ('robocopy /l * \ \ /ns /nc /ndl /nfl /np /njh /XF * /XD *') do (
        set "dow=%%D"
        set "month=%%E"
        set "day=%%F"
        set "HH=%%G"
        set "MM=%%H"
        set "SS=%%I"
        set "year=%%J"
    )
    
    echo Day of the week: %dow%
    echo Day of the month : %day%
    echo Month : %month%
    echo hour : %HH%
    echo minutes : %MM%
    echo seconds : %SS%
    echo year : %year%
    endlocal
    

    가 다른 Windows 스크립트 언어를 사용하는 방법은 세 가지가 더 있습니다.예를 들어 연중 몇 주, 몇 밀리초 단위의 시간을 얻을 수 있는 등 유연성이 향상됩니다.

  3. JScript/BATCH 하이브리드(로 저장 필요).batJScript 는 Windows NT 이후의 모든 시스템에서 Windows Script Host 의 일부로서 사용할 수 있습니다(레지스트리에서는 무효로 할 수 있습니다만, 극히 드문 경우입니다).

    @if (@X)==(@Y) @end /* ---Harmless hybrid line that begins a JScript comment
    
    @echo off
    cscript //E:JScript //nologo "%~f0"
    exit /b 0
    *------------------------------------------------------------------------------*/
    
    function GetCurrentDate() {
        // Today date time which will used to set as default date.
        var todayDate = new Date();
        todayDate = todayDate.getFullYear() + "-" +
                       ("0" + (todayDate.getMonth() + 1)).slice(-2) + "-" +
                       ("0" + todayDate.getDate()).slice(-2) + " " + ("0" + todayDate.getHours()).slice(-2) + ":" +
                       ("0" + todayDate.getMinutes()).slice(-2);
    
        return todayDate;
    }
    
    WScript.Echo(GetCurrentDate());
    
  4. VBScript/BATCH 하이브리드(일시 파일을 사용하지 않고 배치 파일 내에 VBScript를 삽입하여 실행할 수 있습니까?)는 jscript와 같은 케이스이지만 하이브리드는 그다지 완벽하지 않습니다.

    :sub echo(str) :end sub
    echo off
    '>nul 2>&1|| copy /Y %windir%\System32\doskey.exe %windir%\System32\'.exe >nul
    '& echo current date:
    '& cscript /nologo /E:vbscript "%~f0"
    '& exit /b
    
    '0 = vbGeneralDate - Default. Returns date: mm/dd/yy and time if specified: hh:mm:ss PM/AM.
    '1 = vbLongDate - Returns date: weekday, monthname, year
    '2 = vbShortDate - Returns date: mm/dd/yy
    '3 = vbLongTime - Returns time: hh:mm:ss PM/AM
    '4 = vbShortTime - Return time: hh:mm
    
    WScript.echo  Replace(FormatDateTime(Date, 1), ", ", "-")
    
  5. PowerShell - 를 탑재한 모든 머신에 설치할 수 있습니다.NET - Microsoft에서 다운로드(v1, v2, v3(Windows 7 이상만 해당)Windows 7/Win2008 이후의 모든 기기에 기본적으로 설치됩니다.

    C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
    
  6. 셀프 컴파일 jscript.net/batch (가 없는 Windows 머신은 본 적이 없습니다).NET에서는, 꽤 휴대성이 있다고 생각합니다).

    @if (@X)==(@Y) @end /****** silent line that start jscript comment ******
    
    @echo off
    ::::::::::::::::::::::::::::::::::::
    :::       Compile the script    ::::
    ::::::::::::::::::::::::::::::::::::
    setlocal
    if exist "%~n0.exe" goto :skip_compilation
    
    set "frm=%SystemRoot%\Microsoft.NET\Framework\"
    :: searching the latest installed .net framework
    for /f "tokens=* delims=" %%v in ('dir /b /s /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do (
        if exist "%%v\jsc.exe" (
            rem :: the javascript.net compiler
            set "jsc=%%~dpsnfxv\jsc.exe"
            goto :break_loop
        )
    )
    echo jsc.exe not found && exit /b 0
    :break_loop
    
    
    call %jsc% /nologo /out:"%~n0.exe" "%~dpsfnx0"
    ::::::::::::::::::::::::::::::::::::
    :::       End of compilation    ::::
    ::::::::::::::::::::::::::::::::::::
    :skip_compilation
    
    "%~n0.exe"
    
    exit /b 0
    
    
    ****** End of JScript comment ******/
    import System;
    import System.IO;
    
    var dt=DateTime.Now;
    Console.WriteLine(dt.ToString("yyyy-MM-dd hh:mm:ss"));
    
  7. 로그맨 이것은 년도와 요일을 가져올 수 없습니다.비교적 느리고 임시 파일도 생성되며 로그인이 로그 파일에 저장하는 타임스탬프를 기반으로 합니다.Windows XP 이후로는 모두 동작합니다.아마 저를 포함한 누구에게도 이용되지 않을 것입니다만, 또 하나의 방법입니다.

    @echo off
    setlocal
    del /q /f %temp%\timestampfile_*
    
    Logman.exe stop ts-CPU 1>nul 2>&1
    Logman.exe delete ts-CPU 1>nul 2>&1
    
    Logman.exe create counter ts-CPU  -sc 2 -v mmddhhmm -max 250 -c "\Processor(_Total)\%% Processor Time" -o %temp%\timestampfile_ >nul
    Logman.exe start ts-CPU 1>nul 2>&1
    
    Logman.exe stop ts-CPU >nul 2>&1
    Logman.exe delete ts-CPU >nul 2>&1
    for /f "tokens=2 delims=_." %%t in  ('dir /b %temp%\timestampfile_*^&del /q/f %temp%\timestampfile_*') do set timestamp=%%t
    
    echo %timestamp%
    echo MM: %timestamp:~0,2%
    echo dd: %timestamp:~2,2%
    echo hh: %timestamp:~4,2%
    echo mm: %timestamp:~6,2%
    
    endlocal
    exit /b 0
    

Get-Date 함수에 대한 자세한 정보.


@ProVi의 답변에 따르면 필요한 포맷에 맞게 변경하기만 하면 됩니다.

echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%

돌아온다

yyyy-MM-dd hh:mm:ss
2015-09-15 18:36:11

편집 @Jeb 코멘트에 따라 위의 시간 형식은 DATE/T 명령이 반환된 경우에만 작동합니다.

ddd dd/mm/yyyy
Thu 17/09/2015

사용자의 로케일에 맞게 쉽게 편집할 수 있지만 관련된 %DATE% 환경변수에 의해 반환되는 문자열 내의 각 문자의 인덱싱을 사용하면 필요한 문자열 부분을 추출할 수 있습니다.

예를 들어 %DATE~10.4%를 사용하면 DATE 환경변수가 확장되고 확장된 결과의 11번째(오프셋 10) 문자로 시작하는 4개의 문자만 사용됩니다.

예를 들어 미국식 날짜를 사용하는 경우 다음 사항이 적용됩니다.

ddd mm/dd/yyyy
Thu 09/17/2015

echo %DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
2015-09-17 18:36:11

나는 조이의 방식이 정말 마음에 들었지만, 좀 더 자세히 설명해야겠다고 생각했다.

이 방법에서는 코드를 여러 번 실행할 수 있으며, 이미 정의되어 있기 때문에 오래된 날짜 값이 "계속"되는 것에 대해 걱정할 필요가 없습니다.

이 배치 파일을 실행할 때마다 ISO 8601 호환 가능한 날짜 및 시간 표현이 출력됩니다.

FOR /F "skip=1" %%D IN ('WMIC OS GET LocalDateTime') DO (SET LIDATE=%%D & GOTO :GOT_LIDATE)
:GOT_LIDATE
SET DATETIME=%LIDATE:~0,4%-%LIDATE:~4,2%-%LIDATE:~6,2%T%LIDATE:~8,2%:%LIDATE:~10,2%:%LIDATE:~12,2%
ECHO %DATETIME%

이 버전에서는 레이블이 중복될 수 있으므로 파일의 여러 위치에 동일한 코드를 복사/붙이지 않도록 주의해야 합니다.각 복사본에 별도의 라벨을 붙이거나 이 코드를 자체 배치 파일에 넣고 필요한 경우 소스 파일에서 호출할 수 있습니다.

이것은 시간을 포함하고 부품을 0으로 채우겠다는 Joey의 답변의 연장선입니다.

예를 들어, 결과는 2019-06-01_17-25-36이 됩니다.또, 이것은 UTC 시각입니다.

  for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x

  set Month=0%Month%
  set Month=%Month:~-2%
  set Day=0%Day%
  set Day=%Day:~-2%
  set Hour=0%Hour%
  set Hour=%Hour:~-2%
  set Minute=0%Minute%
  set Minute=%Minute:~-2%
  set Second=0%Second%
  set Second=%Second:~-2%

  set TimeStamp=%Year%-%Month%-%Day%_%Hour%-%Minute%-%Second%

PowerShell을 사용하고 루프를 사용하여 출력을 환경변수로 리디렉션할 수 있습니다.

명령줄에서 (cmd):

for /f "tokens=*" %a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%a

echo %td%
2016-25-02+17:25

배치 파일에서 탈출할 수 있습니다.%a~하듯이%%a:

for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%%a

를 사용합니다.%date%변수:

echo %date%

이것 좀 봐.

for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "MS=%dt:~15,3%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" & set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%-%MS%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause

다음과 같이 환경변수를 원하는 숫자 형식의 값으로 설정합니다.

FOR /F "tokens=1,2,3,4 delims=/ " %a IN ('echo %date%') DO set DateRun=%d-%b-%c

날짜 및 시간 형식은 위치 고유 정보이므로 %date% 및 %time% 변수에서 검색하려면 형식 변환을 사용하여 문자열을 구문 분석해야 합니다.API를 사용하여 데이터 구조를 가져오고 원하는 대로 해석하는 것이 좋습니다.WMIC은 좋은 선택입니다.다음 예제에서는 Win32_LocalTime을 사용합니다.Win32_CurrentTime 또는 Win32_UTCTime를 사용할 수도 있습니다.

@echo off  
SETLOCAL ENABLEDELAYEDEXPANSION  
for /f %%x in ('wmic path Win32_LocalTime get /format:list ^| findstr "="') do set %%x  
set yyyy=0000%Year%  
set mmmm=0000%Month%  
set dd=00%Day%  
set hh=00%Hour%  
set mm=00%Minute%  
set ss=00%Second%  
set ts=!yyyy:~-4!-!mmmm:~-2!-!dd:~-2!_!hh:~-2!:!mm:~-2!:!ss:~-2!  
echo %ts%  
ENDLOCAL  

결과:
2018-04-25_10:03:11

다음을 사용하고 있습니다.

set iso_date=%date:~6,4%-%date:~3,2%-%date:~0,2%

또는 로그 파일 이름 'MyLogFileName'과 함께 다음을 수행합니다.

set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName
echo %DATE:~10,4%%DATE:~7,2%%DATE:~4,2% 

Python이 설치되어 있으면 다음을 수행할 수 있습니다.

python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))"

필요에 따라 쉽게 포맷 문자열을 조정할 수 있습니다.

powershell을 사용할 수 있는 경우 다음 코드를 사용할 수 있습니다.

# get date
$BuildDate=(get-date -format "yyMMdd")
echo BuildDate=$BuildDate

# get time
$BuildTime=(get-date -format "hhmmss")
echo BuildTime=$BuildTime

결과는 다음과 같습니다.

BuildDate=200518
BuildTime=115919

신뢰성이 높은 솔루션을 입수하는 데 10~30분 정도 투자해도 괜찮으시다면(Windows의 지역 설정에 의존하지 않습니다), 계속 읽어보시기 바랍니다.

마음을 자유롭게 합시다.이렇게 스크립트를 단순화하시겠습니까?(LOG_DATETIME 변수를 설정하는 것을 전제로 합니다).

FOR /F "tokens=* USEBACKQ" %%F IN (`FormatNow "yyyy-MM-dd"`) DO (
  Set LOG_DATETIME=%%F
)

echo I am going to write log to Testing_%LOG_DATETIME%.log

넌 할 수 있다.C#을 사용하여 FormatNow.exe를 빌드하기만 하면 됩니다.NET을 사용하여 PATH에 추가합니다.

주의:

  1. Visual Studio Express와 같은 모든 Visual Studio 버전을 사용하여 FormatNow.exe를 빌드할 수 있습니다.
  2. Visual Studio에서 "Windows Forms Application" 프로젝트가 아닌 "Console Application" C# 프로젝트를 선택합니다.
  3. 상식: 빌드된 FormatNow.exe에는 이 필요합니다.실행할 NET Framework.
  4. 상식: FormatNow.exe를 PATH 변수에 추가한 후 CMD를 다시 시작해야 합니다.환경변수의 변경에도 적용됩니다.

이점:

  1. 느리지 않다(0.2초 이내에 완료).
  2. 많은 형식이 https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx 에서 지원됩니다.요일만 가져오려면 Format Now "ddd", 연도만 가져오려면 Format Now "yyy"
  3. Windows 의 지역 설정에 의존하지 않기 때문에, 출력의 신뢰성이 높아집니다.한편, %date%는 다른 컴퓨터에서 일관된 형식을 제공하지 않으며 신뢰할 수 없습니다.
  4. CMD 변수를 너무 많이 생성하여 변수 네임스페이스를 오염시킬 필요가 없습니다.
  5. 프로그램을 호출하여 결과를 얻으려면 배치 스크립트에 3줄이 필요합니다.그것은 충분히 짧아야 한다.

Visual Studio 2010을 사용하여 빌드한 FormatNow.exe의 소스 코드(알 수 없는 악성 프로그램을 다운로드하는 위험을 피하기 위해 직접 빌드하는 것이 좋습니다).아래 코드를 복사하여 붙여넣기만 하면 프로그램을 한 번 빌드할 수 있습니다.그러면 향후 모든 용도에 사용할 수 있는 신뢰할 수 있는 날짜 포맷을 얻을 수 있습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace FormatNow
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (args.Length < 1)
                {
                    throw new ArgumentException("Missing format");
                }
                string format = args[0];
                Console.Write(DateTime.Now.ToString(format, CultureInfo.InvariantCulture.DateTimeFormat));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

    }
}

일반적으로 복잡한 로직을 처리할 때 매우 작은 프로그램을 작성하고 프로그램을 호출하여 출력을 배치 스크립트 변수로 다시 캡처함으로써 작업을 단순화할 수 있습니다.우리는 학생이 아니며 문제를 해결하기 위해 배치 스크립트만의 규칙을 따르는 시험을 치르지 않습니다.실제 작업 환경에서는 모든 (합법적인) 방법이 허용됩니다.많은 간단한 작업에 대한 회피책이 필요한 Windows 배치 스크립트의 부족한 기능을 계속 사용해야 하는 이유는 무엇입니까?왜 우리가 그 일에 잘못된 도구를 사용해야 하는가?

언급URL : https://stackoverflow.com/questions/10945572/windows-batch-formatted-date-into-variable

반응형