Log date and time accurately with batch file












1















I have a batch file that backups my files and works nicely, however I wanted to be able to log the exact time each task starts, but it is not working as I expected.



@echo off
> C:log%date:~3,2%-%date:~0,2%.log (
echo %time% - Backing up first part
... some logic
echo %time% - Backing up second part
...
)


The problem is that I get the exact same time for both instances of %time%, instead of displaying the exact time as I wanted.



I assume it has something to do with delayed expansion, maybe DOS assigns a value to time the first time around and keeps that value througout the whole file.



What should I do to be able to reflect the time at which the echo is actually called?










share|improve this question



























    1















    I have a batch file that backups my files and works nicely, however I wanted to be able to log the exact time each task starts, but it is not working as I expected.



    @echo off
    > C:log%date:~3,2%-%date:~0,2%.log (
    echo %time% - Backing up first part
    ... some logic
    echo %time% - Backing up second part
    ...
    )


    The problem is that I get the exact same time for both instances of %time%, instead of displaying the exact time as I wanted.



    I assume it has something to do with delayed expansion, maybe DOS assigns a value to time the first time around and keeps that value througout the whole file.



    What should I do to be able to reflect the time at which the echo is actually called?










    share|improve this question

























      1












      1








      1








      I have a batch file that backups my files and works nicely, however I wanted to be able to log the exact time each task starts, but it is not working as I expected.



      @echo off
      > C:log%date:~3,2%-%date:~0,2%.log (
      echo %time% - Backing up first part
      ... some logic
      echo %time% - Backing up second part
      ...
      )


      The problem is that I get the exact same time for both instances of %time%, instead of displaying the exact time as I wanted.



      I assume it has something to do with delayed expansion, maybe DOS assigns a value to time the first time around and keeps that value througout the whole file.



      What should I do to be able to reflect the time at which the echo is actually called?










      share|improve this question














      I have a batch file that backups my files and works nicely, however I wanted to be able to log the exact time each task starts, but it is not working as I expected.



      @echo off
      > C:log%date:~3,2%-%date:~0,2%.log (
      echo %time% - Backing up first part
      ... some logic
      echo %time% - Backing up second part
      ...
      )


      The problem is that I get the exact same time for both instances of %time%, instead of displaying the exact time as I wanted.



      I assume it has something to do with delayed expansion, maybe DOS assigns a value to time the first time around and keeps that value througout the whole file.



      What should I do to be able to reflect the time at which the echo is actually called?







      windows batch ms-dos






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 28 at 15:33









      Luis Esparza LeedMxLuis Esparza LeedMx

      478




      478






















          1 Answer
          1






          active

          oldest

          votes


















          5














          Classic delayed expansion issue.



          Your problem is that %time% expansion occurs when the statement is parsed, and the entire parenthesized block is parsed at the same time, before any commands are executed.



          There are three possible solutions:



          1) Use TIME /T instead



          This avoids the whole issue of expansion timing. But the format is different, and there is a newline after the time, so you can't add a label to the end.



          time /t
          echo Backing up first part


          If you want the label on the same line, then you could reverse the order and use SET /P



          <nul set /p "Backing up first part - "
          time /t


          Or you can capture the output with a FOR /F loop and put everything on one line



          for /f "delims=" %%T in ('time /t') do echo %%T - Backing up first part:


          2) Use CALL and doubled percents to get an extra round of parsing



          call echo %%time%% - Backing up first part:


          See How does the Windows Command Interpreter (CMD.EXE) parse scripts? for an understanding of why this works. Phases 1 and 6 are relevant here. But be forewarned - it is a lot of very dense material that will take time to digest.



          3) Use delayed expansion



          This is the technique that I prefer to use.



          This is much faster than the CALL hack. It requires SETLOCAL to enable delayed expansion, and use of ! instead of % to expand the variable:



          setlocal enableDelayedExpansion
          > C:log%date:~3,2%-%date:~0,2%.log (
          echo !time! - Backing up first part
          ... some logic
          echo !time! - Backing up second part
          ...
          )





          share|improve this answer























            Your Answer








            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "3"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f1399306%2flog-date-and-time-accurately-with-batch-file%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            5














            Classic delayed expansion issue.



            Your problem is that %time% expansion occurs when the statement is parsed, and the entire parenthesized block is parsed at the same time, before any commands are executed.



            There are three possible solutions:



            1) Use TIME /T instead



            This avoids the whole issue of expansion timing. But the format is different, and there is a newline after the time, so you can't add a label to the end.



            time /t
            echo Backing up first part


            If you want the label on the same line, then you could reverse the order and use SET /P



            <nul set /p "Backing up first part - "
            time /t


            Or you can capture the output with a FOR /F loop and put everything on one line



            for /f "delims=" %%T in ('time /t') do echo %%T - Backing up first part:


            2) Use CALL and doubled percents to get an extra round of parsing



            call echo %%time%% - Backing up first part:


            See How does the Windows Command Interpreter (CMD.EXE) parse scripts? for an understanding of why this works. Phases 1 and 6 are relevant here. But be forewarned - it is a lot of very dense material that will take time to digest.



            3) Use delayed expansion



            This is the technique that I prefer to use.



            This is much faster than the CALL hack. It requires SETLOCAL to enable delayed expansion, and use of ! instead of % to expand the variable:



            setlocal enableDelayedExpansion
            > C:log%date:~3,2%-%date:~0,2%.log (
            echo !time! - Backing up first part
            ... some logic
            echo !time! - Backing up second part
            ...
            )





            share|improve this answer




























              5














              Classic delayed expansion issue.



              Your problem is that %time% expansion occurs when the statement is parsed, and the entire parenthesized block is parsed at the same time, before any commands are executed.



              There are three possible solutions:



              1) Use TIME /T instead



              This avoids the whole issue of expansion timing. But the format is different, and there is a newline after the time, so you can't add a label to the end.



              time /t
              echo Backing up first part


              If you want the label on the same line, then you could reverse the order and use SET /P



              <nul set /p "Backing up first part - "
              time /t


              Or you can capture the output with a FOR /F loop and put everything on one line



              for /f "delims=" %%T in ('time /t') do echo %%T - Backing up first part:


              2) Use CALL and doubled percents to get an extra round of parsing



              call echo %%time%% - Backing up first part:


              See How does the Windows Command Interpreter (CMD.EXE) parse scripts? for an understanding of why this works. Phases 1 and 6 are relevant here. But be forewarned - it is a lot of very dense material that will take time to digest.



              3) Use delayed expansion



              This is the technique that I prefer to use.



              This is much faster than the CALL hack. It requires SETLOCAL to enable delayed expansion, and use of ! instead of % to expand the variable:



              setlocal enableDelayedExpansion
              > C:log%date:~3,2%-%date:~0,2%.log (
              echo !time! - Backing up first part
              ... some logic
              echo !time! - Backing up second part
              ...
              )





              share|improve this answer


























                5












                5








                5







                Classic delayed expansion issue.



                Your problem is that %time% expansion occurs when the statement is parsed, and the entire parenthesized block is parsed at the same time, before any commands are executed.



                There are three possible solutions:



                1) Use TIME /T instead



                This avoids the whole issue of expansion timing. But the format is different, and there is a newline after the time, so you can't add a label to the end.



                time /t
                echo Backing up first part


                If you want the label on the same line, then you could reverse the order and use SET /P



                <nul set /p "Backing up first part - "
                time /t


                Or you can capture the output with a FOR /F loop and put everything on one line



                for /f "delims=" %%T in ('time /t') do echo %%T - Backing up first part:


                2) Use CALL and doubled percents to get an extra round of parsing



                call echo %%time%% - Backing up first part:


                See How does the Windows Command Interpreter (CMD.EXE) parse scripts? for an understanding of why this works. Phases 1 and 6 are relevant here. But be forewarned - it is a lot of very dense material that will take time to digest.



                3) Use delayed expansion



                This is the technique that I prefer to use.



                This is much faster than the CALL hack. It requires SETLOCAL to enable delayed expansion, and use of ! instead of % to expand the variable:



                setlocal enableDelayedExpansion
                > C:log%date:~3,2%-%date:~0,2%.log (
                echo !time! - Backing up first part
                ... some logic
                echo !time! - Backing up second part
                ...
                )





                share|improve this answer













                Classic delayed expansion issue.



                Your problem is that %time% expansion occurs when the statement is parsed, and the entire parenthesized block is parsed at the same time, before any commands are executed.



                There are three possible solutions:



                1) Use TIME /T instead



                This avoids the whole issue of expansion timing. But the format is different, and there is a newline after the time, so you can't add a label to the end.



                time /t
                echo Backing up first part


                If you want the label on the same line, then you could reverse the order and use SET /P



                <nul set /p "Backing up first part - "
                time /t


                Or you can capture the output with a FOR /F loop and put everything on one line



                for /f "delims=" %%T in ('time /t') do echo %%T - Backing up first part:


                2) Use CALL and doubled percents to get an extra round of parsing



                call echo %%time%% - Backing up first part:


                See How does the Windows Command Interpreter (CMD.EXE) parse scripts? for an understanding of why this works. Phases 1 and 6 are relevant here. But be forewarned - it is a lot of very dense material that will take time to digest.



                3) Use delayed expansion



                This is the technique that I prefer to use.



                This is much faster than the CALL hack. It requires SETLOCAL to enable delayed expansion, and use of ! instead of % to expand the variable:



                setlocal enableDelayedExpansion
                > C:log%date:~3,2%-%date:~0,2%.log (
                echo !time! - Backing up first part
                ... some logic
                echo !time! - Backing up second part
                ...
                )






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 28 at 16:21









                dbenhamdbenham

                7,91142030




                7,91142030






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Super User!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f1399306%2flog-date-and-time-accurately-with-batch-file%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Terni

                    A new problem with tex4ht and tikz

                    Sun Ra