0

I was working to a script that I needed to read the time from the system with seconds but not milliseconds. I noticed that some computers have a different region settings that did caused me a few problems like the date from one computer is shown as 01/01/2020, the other one with 01.01.2020 using the command %date% etc.

Same thing if I use the command %time%, some computers is shown a time like 12:13:14,15, some like 12:13:14.16.

Now, to solve this problem I have to create a variable to read the separator symbol and output the correct one. For the command date It was simple.

For time I have this command:

FOR /F "tokens=3 delims=0123456789" %%A IN ('echo %time%') DO set timeSeparatorSymbol=%%A

If the computer have the symbol for separator for milliseconds as . then the output is:

timeSeparatorSymbol=.

Which is good.

If the computer have the symbol for separator for milliseconds as , then the output is:

timeSeparatorSymbol=

As you see, the variable is not created and I'm struggling figure it out why the comma doesn't accept it as a variable.

I need this for the following script to works to all computers no matter the regional settings:

for /f "tokens=3 delims=:%timeSeparatorSymbol%" %%A in ('echo %time%') do set second=%%A

Thank you in advance.

JaJe
  • 3
  • 3
  • 1
    I suggest to use `FOR /F "tokens=3 delims=0123456789" %%I IN ("%time%") DO echo set "timeSeparatorSymbol=%%I"` which is much faster as there is not started one more command process with `%ComSpec% /c` and `echo 11:59:20,15` appended as additional arguments in background for capturing the output and processing by __FOR__ after started `cmd.exe` terminated. The comma outside a double quoted argument string is interpreted as argument separator by `cmd.exe` and for that reason replaced by a space character. So executed in separate cmd process is `echo 11:59:20 15`. – Mofi Jan 27 '20 at 11:02
  • 1
    Do you know that the region dependent date format can be without or with abbreviated weekday and comma at beginning and the date itself can be in format `dd.MM.yyyy` or `dd/MM/yyyy` or `MM/dd/yyyy`? Good luck on finding out if first is month and second is day or first is day and second is month on using region dependent date/time. See also Wikipedia article about [date format by country](https://en.wikipedia.org/wiki/Date_format_by_country). – Mofi Jan 27 '20 at 11:08
  • See also [How do I get current date/time on the Windows command line in a suitable format for usage in a file/folder name?](https://stackoverflow.com/questions/203090/) and [Why does %date% produce a different result in batch file executed as scheduled task?](https://stackoverflow.com/a/44670322/3074564) and [Windows batch command to create backup folder and replace folder](https://stackoverflow.com/a/57189369/3074564). I suggest to use region independent solution with `wmic` to get date and time with millisecond although `wmic` takes a long time before printing the result. – Mofi Jan 27 '20 at 11:16
  • See [this answer written by Compo](https://stackoverflow.com/a/58590070/3074564) using `robocopy` to get current date and time without millisecond in a region independent format if the usage of `%SystemRoot%\System32\robocopy.exe` is possible, i.e. the batch file must not support Windows XP or even older versions of Windows on which robocopy.exe is not available (by default). The `robocopy` solution is faster than the correct coded `wmic` solution. – Mofi Jan 27 '20 at 11:23
  • @Mofi That was Extremelly simple by replacing 'echo %time%' with "%time%" only. How I didn't think about that! Thank you! Yes, I know that format date could be different from country to country but it's not the case, here all computers have DD/MM/YYYY but only the symbol different. – JaJe Jan 27 '20 at 12:14
  • Date format in cmd: `for /f "tokens=2 delims=[]" %? in ('echo.^|date') do @echo %?` – penknife Feb 01 '20 at 07:37

3 Answers3

0

Had you searched this site, you'd have found a huge amount of questions and answers requring a method of returning dates and/or times in a consistent format.

The method below, shows one such method of getting the current time in hh:mm:ss format, it uses robocopy.exe as linked by @Mofi in their recent comment:

@Set "TimeStamp="
@For /F "Tokens=2" %%A In (
    '^""%__AppDir__%Robocopy.exe" /NJH /L "\|" Null^"'
) Do @If Not Defined TimeStamp Set "TimeStamp=%%A"
@Echo=%TimeStamp%
@Timeout 5

If you don't want the 'complication' of being robust, try this:

For /F "Tokens=2" %%A In ('RoboCopy /NJH /L "\|" Null^|Find ":"') Do Set "TimeStamp=%%A"


If you only wanted to retrieve the seconds, i.e ss, (it is unclear from your question):
@Set "Seconds="
@For /F "Tokens=4Delims=: " %%A In (
    '^""%__AppDir__%Robocopy.exe" /NJH /L "\|" Null^"'
) Do @If Not Defined Seconds Set "Seconds=%%A"
@Echo=%Seconds%
@Timeout 5

…and once again without the 'complication':

For /F "Tokens=4Delims=: " %%A In ('RoboCopy /NJH /L "\|" Null^|Find ":"') Do Set "Seconds=%%A"
Compo
  • 30,301
  • 4
  • 20
  • 32
  • Thank you, but this solution seems too complicated to do. @Mofi gave the right answer by simply replacing 'echo %time%' with "%time%" and now everything works as intended. – JaJe Jan 27 '20 at 12:17
  • What is complicated about it @JaJe? I have added another version above removing the parts of my code to make it robust. That means I have not complicated matters by **1.** making sure there isn't already a defined `%TimeStamp%` variable, **2.** ensuring that the content of `%PATH%` and/or `%PATHEXT%`, have not been modified/broken. **3.** outputting the variable content. **4.** adding a delay to allow for reading the output, _(for case of cmd.exe closing)_. **5.** ensuring that echoing is turned off. Please feel frre to post your uncomplicated solution, for 'degree of complication' comparison. – Compo Jan 27 '20 at 12:52
  • I tried to read the code you posted which works but it's hard to understand the logic behind like '^""%__AppDir__%Robocopy.exe" /NJH /L "\|" Null^"' I'm lost here. However, using these: FOR /F "tokens=3 delims=0123456789" %%A IN ("%time%") DO set timeSeparatorSymbol=%%A for /f "tokens=3 delims=:%timeSeparatorSymbol%" %%A in ("%time%") do set second=%%A The output is: second=*any second number* Which I can use to compare later in the code. – JaJe Jan 27 '20 at 13:27
  • @JaJe, had you clicked on the link @Mofi provided in their comment, _which I additionally linked to in my answer_, it actually explained what was happening. I am asking RoboCopy to do something it cannot do, i.e. copy the content of a directory named `|` in the root of the current drive, `\ `, _(the vertical bar is invalid if file or directory names)_. It outputs an error message over two lines which will always hold the date and time, in a consistent format, on the first line. It is that I am parsing to retrieve the date and/or time information as necessary. – Compo Jan 27 '20 at 13:40
0

After re-reading your question, and based upon my interpretation that your only issue is the difference in separator types between seconds and milliseconds, and that they are always either , or ., I would offer this alternative:

For /F "Tokens=3 Delims=:" %%A In ("%TIME:,=.%") Do Set "second=%%~nA"

If you were wanting the timestamp as hms, then perhaps this will suffice:

For %%A In ("%TIME:,=.%") Do Set "TimeStamp=%%~nA"

If you just want to ensure that %TIME% always uses a . instead of , just use the variable directly like this: %TIME:,=.%

Compo
  • 30,301
  • 4
  • 20
  • 32
  • if your interpretation is correct, then `%time:~0,8%` (`HH:mm:ss`) or `%time~-2%` (`ms`) should do. – Stephan Jan 27 '20 at 13:58
  • Also this methos is great! In fact, all methods shown by everybody are nice to see and learn. Thank you! – JaJe Jan 27 '20 at 14:23
  • Yes @Stephan, but the OP has not made clear what the possible outputs are for `%TIME%` which means that `%TIME:~,8%` would be dependent upon guarantees that their output wasn't `1:23:46.57`, or `1:23:46,57`; and `%TIME:~-3%` would require that `%TIME%` doesn't output `1:23:45.56 AM` or `1:23:45,56 AM`. The original answer I made, is irrespective of those unknown variables. – Compo Jan 27 '20 at 14:27
0

Your question has much room for speculation and interpretation.

As I understand, you need the date/time separators to build a valid date/time string.

You claim the format is always hh:mm:ss?xx so you can easily extract the desired separator (?) with:

set "timeSeparatorSymbol=%time:~8,1%"

same for date you claim it's "always DD?MM?YYYY):

set "dateSeparatorSymbol=%date:~2,1%"

Of course this doesn't work when the date format is different from your claim (like for example Mon, 27.01.2020. %date:~-5,1% works as long as the date-string ends with a 4 digit Year and there is a separator before)

Stephan
  • 47,723
  • 10
  • 50
  • 81