getTimestamp.bat for time and date processing

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: getTimestamp.bat for time and date processing

#16 Post by dbenham » 25 Jan 2015 13:37

It is all in the documentation, but it can be confusing differentiating the various options until you get used to it. :twisted:

Code: Select all

-D DateSpec

   Specify the base date and time.
   Default value is current local date and time.
   The DateSpec supports many formats:

     ""    (no value)

       Current date and time - the default

     milliseconds

       A JScript numeric expression that represents the number of
       milliseconds since 1970-01-01 00:00:00 UTC.
       Decimal values are truncated.
       Negative values represent dates prior to 1970-01-01.

     "'Date [Time] [TimeZone]'"

       A string representation of the date and time. The date information
       is required, the time and time zone are optional. Missing time info
       is assumed to be 0 (midnight). Missing time zone info is assumed to
       be local time zone.

       The Date, Time, and TimeZone information can be represented as any
       string that is accepted by the JScript Date.Parse() method.
       There are many formatting options. Documentation is available at:
       http://msdn.microsoft.com/en-us/library/k4w173wk(v=vs.84).aspx

       Examples of equivalent representations of Midnight on January 4,
       2013 assuming local time zone is U.S Eastern Standard Time (EST):

         '1-4-2013'                    Defaults to local time zone
         "'January 4, 2013 EST'"       Explicit Eastern Std Time (US)
         "'2013/1/4 -05'"              Explicit Eastern Std Time (US)
         "'Jan 3 2013 23: CST'"        Central Standard Time (US)
         "'2013 3 Jan 9:00 pm -0800'"  Pacific Standard Time (US)
         "'01/04/2013 05:00:00 UTC'"   Universal Coordinated Time
         "'1/4/2013 05:30 +0530'"      India Standard Time

     "year, month[, day[, hour[, minute[, second[, millisecond]]]]]"

       A comma delimited list of numeric JScript expressions representing
       various components of date and time. Year and month are required,
       the rest are optional. Missing values are treated as 0.
       Decimal values are truncated. A 0 month represents January.
       A 1 day represents the first day of the month. A 0 day represents
       the last day of the prior month. The date/time value is always
       in local time. There is no mechanism to specify a time zone.


When specifying the date as a string, you must remember to enclose the value in single quotes. The single quotes are for JScript to signify a string. The value must also be enclosed by double quotes in order for batch to treat the value with spaces as a single argument.

Code: Select all

C:\test>gettimestamp /D "'01/25/2015 11:55 AM'" /F "{UH}"
395056


When specifying the date as a comma delimited list of integral values, you must remember that months are zero based: 0=January, 1=February, etc.

Code: Select all

C:\test>gettimestamp /D "2015,0,25,11,25"
2015-01-25T11:25:00.000-05:00


Dave Benham

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: getTimestamp.bat for time and date processing

#17 Post by Squashman » 25 Jan 2015 13:52

Thanks Dave,
I should have looked at the examples more closely. That all makes perfect sense now.

The stuff you do with Jscript is quite amazing.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: getTimestamp.bat for time and date processing

#18 Post by foxidrive » 30 Jan 2015 05:33

Hi Dave,

It turned out that mkvmerge.exe doesn't give info for filetypes other than MKV so I can't get the elapsed time as per my recent question.
MediaInfo from Sourceforge will return the duration of each media file - can you please offer some advice in how to add the time in this format for each call?
00:25:00.009

I tried to get some info from gettimestamp using this code, and the two versions of the r variable, but I'm not clear how to make gettimestamp accept the format.

My goal is to add sets of times in the same way as the previous solution that you provided.

Code: Select all

@echo off
call :chapter '00:25:00.009'
pause
goto :eof

:chapter
set "r={hh}:{nn}:{ss}.{fff} <ChapterTimeStart>{hh}:{nn}:{ss}.{fff}</ChapterTimeStart>"
set "r={ums} <ChapterTimeStart>{hh}:{nn}:{ss}.{fff}</ChapterTimeStart>"
echo "%~1"
 for /f "tokens=1,2" %%x in (
 'getTimestamp /d "%~1" /z 0 /f "%r%" ') do (
 set "chapterTime=%%x"
 echo %%y
 )



FWIW this line is how I get the time from mediainfo into a routine

Code: Select all

for /f "delims=" %%a in ('" "c:\Util\MediaInfo\MediaInfo.exe" -f --output=General;%%Duration/String3%% "%~1" "') do call :chapter %%~a


This was the code to add time in this format if it helps.

Code: Select all

@echo off
setlocal enableDelayedExpansion
set "chapterTime=0"
for %%T in (
  1267720000000
  1277400000000
  1292405000000
  1268108000000
  1277756000000
  2994983000000
  1024579200000
  1284500000000
  2617460000000
  1291960000000
) do for /f "tokens=1,2" %%A in (
  'getTimestamp /d "!chapterTime!+%%T/1000000" /z 0 /f "{ums} <ChapterTimeStart>{hh}:{nn}:{ss}.{fff}</ChapterTimeStart>"'
) do (
  set "chapterTime=%%A"
  echo %%B
)
pause

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: getTimestamp.bat for time and date processing

#19 Post by foxidrive » 30 Jan 2015 18:46

EDIT: Gah! Stupid me. comma's in a call command need to be quoted. D'uh!


Well I studied the documentation further for gettimestamp.bat and I think I understand what it is saying in this regard:


Code: Select all

         "year, month[, day[, hour[, minute[, second[, millisecond]]]]]"

           A comma delimited list of numeric JScript expressions representing
           various components of date and time. Year and month are required,
           the rest are optional. Missing values are treated as 0.
           Decimal values are truncated. A 0 month represents January.
           A 1 day represents the first day of the month. A 0 day represents
           the last day of the prior month. The date/time value is always
           in local time. There is no mechanism to specify a time zone.


So I tested it with this and I get this result, which isn't what I expected.

<ChapterTimeStart>11:00:02.015</ChapterTimeStart>
<ChapterTimeStart>11:00:02.015</ChapterTimeStart>


Shouldn't it return the exact same timestamp that is in the /D field but in this format: 00:25:00.009 ?


Code: Select all

@echo off
:: call :chapter '00:25:00.009'
call :chapter 2015,1,31,00,25,00,009
call :chapter 2015,1,31,0,25,0,9
pause
goto :eof

:chapter
set "r={hh}:{nn}:{ss}.{fff} <ChapterTimeStart>{hh}:{nn}:{ss}.{fff}</ChapterTimeStart>"
 for /f "tokens=1,2" %%x in (
 'getTimestamp /d "%~1" /f "%r%" ') do (
 set "chapterTime=%%x"
 echo %%y
 )

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: getTimestamp.bat for time and date processing

#20 Post by dbenham » 30 Jan 2015 22:30

You need to put quotes around the comma delimited list of numbers so that they are treated as one argument.


Dave Benham

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: getTimestamp.bat for time and date processing

#21 Post by foxidrive » 31 Jan 2015 01:15

Thanks again. I realised soon after posting, edited my post and forgot to hit submit for several hours as someone arrived.

Is this the kind of thing I need to do, to add the terms in hh:nn:ss.fff format, Dave?

Code: Select all

@echo off
set tally=0
call getTimestamp /d "2015,1,31"     /f "{ums}" /r var0

call :chapter "2015,1,31,00,25,00,009"
call :chapter "2015,1,31,00,32,01,011"
pause
goto :eof

:chapter

call getTimestamp /d "%~1-%var0%"    /f "{ums}" /r var1
for /f "tokens=1,2" %%a in (
  ' getTimestamp /d "%var1%+%tally%" /f "{ums} {hh}:{nn}:{ss}.{fff}" /z 0'
  ) do set tally=%%a&echo %%a %%b



It gives me this:

1500009 00:25:00.009
3421018 00:57:01.018
Press any key to continue . . .

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: getTimestamp.bat for time and date processing

#22 Post by dbenham » 31 Jan 2015 09:06

Going back to your original input timestamps:

Code: Select all

  1267720000000
  1277400000000
  1292405000000
  1268108000000
  1277756000000
  2994983000000
  1024579200000
  1284500000000
  2617460000000
  1291960000000

In the new format, they would look like

Code: Select all

  00:21:07.720
  00:21:17.400
  00:21:32.405
  00:21:08.108
  00:21:17.756
  00:49:54.983
  00:17:04.579
  00:21:24.500
  00:43:37.460
  00:21:31.960


We want the times to be computed from the 0 unix time (1/1/1970 00:00:00 UTC). So we initialize the {UMS} value to 0.

The /D option can parse a time stamp in string form to seconds only: '1/1/1970 00:21:07 UTC'. The milliseconds would need to be added using the /OF option, along with the prior {UMS} value.

So here is how I would adapt the prior solution to the new input format:

Code: Select all

@echo off
setlocal
set "chapterTime=0"
for %%A in (
  00:21:07.720
  00:21:17.400
  00:21:32.405
  00:21:08.108
  00:21:17.756
  00:49:54.983
  00:17:04.579
  00:21:24.500
  00:43:37.460
  00:21:31.960
) do for /f "tokens=1,2 delims=." %%B in ("%%A") do for /f "tokens=1,2" %%D in (
  'getTimestamp /d "'1/1/1970 %%B UTC'" /of !chapterTime!+%%C /z 0 /f "{ums} <ChapterTimeStart>{hh}:{nn}:{ss}.{fff}</ChapterTimeStart>"'
) do (
  set "chapterTime=%%D"
  echo %%E
)
pause


Dave Benham

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: getTimestamp.bat for time and date processing

#23 Post by foxidrive » 31 Jan 2015 23:45

Once again, thank you for your gracious help Dave, it works well.



Not meaning to look a gift horse in the mouse - I would like to comment that your documentation in GetTimeStamp.bat is very expansive,
but it could use some extra examples in the help - because it is very unclear how to manipulate all the terms, even though they are all listed.

A simple example is that you use the term milliseconds in the /D help but it is not immediately obvious
if the term has to be typed as "milliseconds" or if it is an integer, and where it is to be used.

If there were more simple examples interspersed in the help then it would help your users to begin experimenting and perhaps sort some things
out in an intuitive way on their own.


I am intending to be constructive in my criticism, as I use jrepl and repl often and now gettimestamp and jeval/jren are there too, along with Antonio's findrepl.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: getTimestamp.bat for time and date processing

#24 Post by foxidrive » 31 Jan 2015 23:51

New post, different theme:

I have one more suggestion - which I have solved here with an extra batch file:

When using the command line and needing to read the help for these tools, I need to type name /?|more and that is a chore because I type it so very often.

It would be very useful to get paged output by simply typing the command name - instead of these:

Code: Select all

c:\>jrepl
ERROR: Insufficient arguments.
(Use JREPL /? to get help.)

c:\>repl
ERROR: Insufficient arguments. Use REPL /? to get help.

c:\>gettimestamp
2015-02-01T16:36:50.320+11:00

c:\>jeval
ERROR: Insufficient arguments. Use jeval /? to get help.

c:\>findrepl
c:\Files\bat\findrepl.bat(318, 1) Microsoft JScript runtime error: Permission denied


I have many ways to solve this - but there are probably many people needing to refer to help often, and having to retype the commands.

Perhaps a /p switch to page the help would be an option - though doing it by default could be very useful.
OR maybe piping it to a file and opening it in notepad so the user can navigate back and forward through the help?

Thanks for all your help - and for the utilities.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: getTimestamp.bat for time and date processing

#25 Post by dbenham » 01 Feb 2015 10:25

Yes, I've thought about putting a few more examples in the documentation, especially for the /D option. I may get around to that some day.

I also thought about automatically piping the help through MORE, but opted against it because I frequently use the help, and I find that MORE gets in my way.

I set up my console window to have a large buffer that allows me to scroll up and see previous output. It is a one time setup.

- launch the console via your favorite shortcut, and right click on the title bar at the top.
- select "properties"
- select the"layout" tab
- my "Screen Buffer Size" is Width=3000, Height=1000
- my "Window Size" is Width=150, Height=45
- Press "OK" to accept the changes. I get those settings every time I use the shortcut.

I haven't played with the "Defaults" option (as opposed to "Properties"). I don't know what "Defaults" does.

You say you use an auxiliary batch script to pipe the help through more. Another option is to define a DOSKEY macro that can be used on the command line to page the output of any command.

Code: Select all

C:\test>doskey m=$*^|more

C:\test>m gettimestamp /?


Perhaps someday I will add an option to the help to utilize MORE, but until then, the above strategies can help.


Dave Benham

Sponge Belly
Posts: 231
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: getTimestamp.bat for time and date processing

#26 Post by Sponge Belly » 01 Feb 2015 11:46

@Foxi

Did you really say “look a gift horse in the mouse”? :lol:

Turn off the computer and go out into the fresh air for a walk! :D

- SB

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: getTimestamp.bat for time and date processing

#27 Post by foxidrive » 02 Feb 2015 05:55

Sponge Belly wrote:@Foxi

Did you really say “look a gift horse in the mouse”? :lol:

Turn off the computer and go out into the fresh air for a walk! :D

- SB


Yes, it looks like I did! :D

I used to love bushwalking - but I'd have to go by wheelchair these days.
I'm not in a wheelchair, but I can't walk far without feeling like crap.


Dave, just an idle comment here but my cmd history buffer is large also but microsoft has a bug with my microsoft trackball - and my scrollwheel doesn't move page-by-page but instead jumps by several pages - so looking back in the cmd history is painful.

This is my batch file to show me the help.

Code: Select all

@echo off
if "%~1"=="" echo f = findrepl r = repl, j = jrepl, e = eval, g = gettimestamp & pause & goto :EOF

set "file=%temp%\readdoc.tmp.txt"
if /i "%~1"=="r"  repl /?>"%file%"&call m1 "%file%"
if /i "%~1"=="j" jrepl /?>"%file%"&call m1 "%file%"
if /i "%~1"=="g" GetTimeStamp /?>"%file%"&call m1 "%file%"
if /i "%~1"=="e" eval /?>"%file%"&call m1 "%file%"
if /i "%~1"=="f" findrepl /?>"%file%"&call m1 "%file%"

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: getTimestamp.bat for time and date processing

#28 Post by dbenham » 12 Jul 2015 15:30

I've released version 2.3

New Formats

I've added new formats for Day of Year:

{DDY} - Day of year number, zero padded to 3 digits
{DY} - Day of year number without padding

I've also added formats for convenient ISO 8601 date and time strings. The form with a dash provides a string with punctuation, and the form without a dash provides a compressed string without punctuation.

{ISO-TS} - date and time as YYYY-MM-DDThh:mm:ss.fff+hh:mm
{ISOTS} - date and time as YYYYMMDDThhmmss.fff+hhmm
{ISO-DT} - date as YYYY-MM-DD
{ISODT} - date as YYYYMMDD
{ISO-TM} - time as hh:mm:ss.fff
{ISOTM} - time as hhmmss.fff
{ISO-TZ} - time zone as +hh:ss (or -hh:ss)
{ISOTZ} - time zone as +hhss (or -hhss)

New paged help option

I've added the -?? option for paged help via MORE. GetTimestamp -?? is the same as (GetTimestamp -? | more) 2>nul. I redirect stderr to nul to avoid "The process tried to write to a nonexistent pipe." error when Q is pressed to abort the help.

User defined option defaults

I now allow user defined option defaults via environment variables of the form "GetTimestamp-Option=Value". For example, the default day of week abbreviations for {WKD} are normally mixed case. You could change the default to upper case abbreviations by defining "GetTimestamp-wkd=SUN MON TUE WED THU FRI". This feature makes it easy to adapt GetTimestamp for any language, without resorting to code modification. The default option variables can be defined within your script, within AutoRun commands defined within the registry, or as User or System variables defined in the registry.

GetTimestamp.bat version 2.3

Code: Select all

@if (@X)==(@Y) @end  /* harmless hybrid line that begins a JScript comment
@goto :batch
::
::getTimestamp.bat version 2.3 by Dave Benham
::
::  Release History:
::    2.3 2015-07-12 - Added {ISO-xx}, {ISOxx}, {DY} and {DDY} formats
::                     Added -?? (paged help) option
::                     Allow user defined default option values by defining
::                     variables of the form "GetTimestamp-Option=Value"
::    2.2 2014-12-03 - Doc fix: -R ReturnVariable is unchanged if err occurs
::    2.1 2014-12-03 - Added GOTO at top to increase performance (32% faster)
::    2.0 2014-12-02 - Major rewrite: most code now in JScript (25% faster)
::                     Better error handling
::                     May now use /Option or -Option
::                     Added -V option
::                     Added {{} format value to enable unambiguous { literal
::    1.1 ????-??-?? - Added -Z option and obscure bug fixes
::    1.0 2013-07-17 - Initial release
::
::============ Documentation ===========
:::
:::getTimestamp  [-option [value]]...
:::
:::  Displays a formatted timestamp. Defaults to the current local date
:::  and time using an ISO 8601 format with milliseconds, time zone
:::  and punctuation.
:::
:::  Returned ERRORLEVEL is 0 upon success, 1 if failure.
:::
:::  Options may be prefaced with - or /
:::
:::  All options have default values. The default value can be overridden by
:::  defining a variable of the form "GetTimestamp-OPTION=VALUE". For example,
:::  upper case English weekday abbreviations can be specified as the default
:::  by defining "GetTimestamp-WKD=SUN MON TUE WED THU FRI SAT".
:::
:::  Command line option values take precedence, followed by environment variable
:::  defaults, followed by built in defaults.
:::
:::  The following options are all case insensitive:
:::
:::    -?  : Prints this documentation for getTimestamp
:::
:::    -?? : Prints this documentation with pagination via MORE
:::
:::    -V  : Prints the version of getTimeStamp
:::
:::    -U  : Returns a UTC timestamp instead of local timestamp.
:::          Default is a local timestamp.
:::
:::    -Z TimeZoneMinuteOffset
:::
:::       Returns the timestamp using the specified time zone offset.
:::       TimeZoneMinuteOffset is a JScript numeric expression that
:::       represents the number of minutes offset from UTC.
:::       Decimal values are truncated.
:::       Default is empty, meaning local timezone.
:::
:::    -D DateSpec
:::
:::       Specify the base date and time.
:::       Default value is current local date and time.
:::       The DateSpec supports many formats:
:::
:::         ""    (no value)
:::
:::           Current date and time - the default
:::
:::         milliseconds
:::
:::           A JScript numeric expression that represents the number of
:::           milliseconds since 1970-01-01 00:00:00 UTC.
:::           Decimal values are truncated.
:::           Negative values represent dates prior to 1970-01-01.
:::
:::         "'Date [Time] [TimeZone]'"
:::
:::           A string representation of the date and time. The date information
:::           is required, the time and time zone are optional. Missing time info
:::           is assumed to be 0 (midnight). Missing time zone info is assumed to
:::           be local time zone.
:::
:::           The Date, Time, and TimeZone information can be represented as any
:::           string that is accepted by the JScript Date.Parse() method.
:::           There are many formatting options. Documentation is available at:
:::           http://msdn.microsoft.com/en-us/library/k4w173wk(v=vs.84).aspx
:::
:::           Examples of equivalent representations of Midnight on January 4,
:::           2013 assuming local time zone is U.S Eastern Standard Time (EST):
:::
:::             '1-4-2013'                    Defaults to local time zone
:::             "'January 4, 2013 EST'"       Explicit Eastern Std Time (US)
:::             "'2013/1/4 -05'"              Explicit Eastern Std Time (US)
:::             "'Jan 3 2013 23: CST'"        Central Standard Time (US)
:::             "'2013 3 Jan 9:00 pm -0800'"  Pacific Standard Time (US)
:::             "'01/04/2013 05:00:00 UTC'"   Universal Coordinated Time
:::             "'1/4/2013 05:30 +0530'"      India Standard Time
:::
:::         "year, month[, day[, hour[, minute[, second[, millisecond]]]]]"
:::
:::           A comma delimited list of numeric JScript expressions representing
:::           various components of date and time. Year and month are required,
:::           the rest are optional. Missing values are treated as 0.
:::           Decimal values are truncated. A 0 month represents January.
:::           A 1 day represents the first day of the month. A 0 day represents
:::           the last day of the prior month. The date/time value is always
:::           in local time. There is no mechanism to specify a time zone.
:::
:::    -OY YearOffset
:::
:::       Specify the number of years to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OM MonthOffset
:::
:::       Specify the number of months to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OD DayOffset
:::
:::       Specify the number of days to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OH HourOffset
:::
:::       Specify the number of hours to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -ON MinuteOffset
:::
:::       Specify the number of minutes to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OS SecondOffset
:::
:::       Specify the number of seconds to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OF MillisecondOffset
:::
:::       Specify the number of milliseconds to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -F FormatString
:::
:::       Specify the timestamp format.
:::       Default is "{ISO-TS}"
:::       Strings within braces are dynamic components.
:::       All other strings are literals.
:::       Available components (case insensitive) are:
:::
:::         {YYYY}  4 digit year, zero padded
:::
:::         {YY}    2 digit year, zero padded
:::
:::         {Y}     year without zero padding
:::
:::         {MONTH} month name, as preferentially specified by:
:::                    1) -MONTH option
:::                    2) GetTimestamp-MONTH environment variable
:::                    3) Mixed case, English month names
:::
:::         {MTH}   month abbreviation, as preferentially specified by:
:::                    1) -MTH option
:::                    2) GetTimestamp-MTH environment variable
:::                    3) Mixed case, English month abbreviations
:::
:::         {MM}    2 digit month number, zero padded
:::
:::         {M}     month number without zero padding
:::
:::         {WEEKDAY} day of week name, as preferentially specified by:
:::                    1) -WEEKDAY option
:::                    2) GetTimestamp-WEEKDAY environment variable
:::                    3) Mixed case, English day names
:::
:::         {WKD}   day of week abbreviation, as preferentially specified by:
:::                    1) -WKD option
:::                    2) GetTimestamp-WKD environment variable
:::                    3) Mixed case, English day abbreviations
:::
:::         {W}     day of week number, 0=Sunday
:::
:::         {DD}    2 digit day of month number, zero padded
:::
:::         {D}     day of month number, without zero padding
:::
:::         {DDY}   3 digit day of year number, zero padded
:::
:::         {DY}    day of year number, without zero padding
:::
:::         {HH}    2 digit hours, 24 hour format, zero padded
:::
:::         {H}     hours, 24 hour format without zero padding
:::
:::         {HH12}  2 digit hours, 12 hour format, zero padded
:::
:::         {H12}   hours, 12 hour format without zero padding
:::
:::         {NN}    2 digit minutes, zero padded
:::
:::         {N}     minutes without padding
:::
:::         {SS}    2 digit seconds, zero padded
:::
:::         {S}     seconds without padding
:::
:::         {FFF}   3 digit milliseconds, zero padded
:::
:::         {F}     milliseconds without padding
:::
:::         {AM}    AM or PM in upper case
:::
:::         {PM}    am or pm in lower case
:::
:::         {ZZZZ}  timezone expressed as minutes offset from UTC,
:::                 zero padded to 3 digits with sign
:::
:::         {Z}     timzone expressed as minutes offset from UTC without padding
:::
:::         {ZS}    ISO 8601 timezone sign
:::
:::         {ZH}    ISO 8601 timezone hours (no sign)
:::
:::         {ZM}    ISO 8601 timezone minutes (no sign)
:::
:::         {TZ}    ISO 8601 timezone in +/-hh:mm format
:::
:::         {ISOTS} YYYYMMDDThhmmss.fff+hhss
:::                 Compressed ISO 8601 date/time (timestamp) with milliseconds
:::                 and time zone
:::
:::         {ISODT} YYYYMMDD
:::                 Compressed ISO 8601 date format
:::
:::         {ISOTM} hhmmss.fff
:::                 Compressed ISO 8601 time format with milliseconds
:::
:::         {ISOTZ} +hhmm
:::                 Compressed ISO 8601 timezone format
:::
:::         {ISO-TS} YYYY-MM-DDThh:mm:ss.fff+hh:ss
:::                  ISO 8601 date/time (timestamp) with milliseconds and time zone
:::
:::         {ISO-DT} YYYY-MM-DD
:::                  ISO 8601 date format
:::
:::         {ISO-TM} hh:mm:ss.fff
:::                  ISO 8601 time format with milliseconds
:::
:::         {ISO-TZ} +hh:mm
:::                  ISO 8601 timezone  (same as {TZ})
:::
:::         {U}     Unix Epoch time: same as {US}
:::                 Seconds since 1970-01-01 00:00:00 UTC.
:::                 Negative numbers represent dates prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UMS}   Milliseconds since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {US}    Seconds since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UM}    Minutes since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UH}    Hours since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UD}    Days since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {USD}   Decimal seconds since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UMD}   Decimal minutes since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UHD}   Decimal hours since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UDD}   Decimal days since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {{}     A { character
:::
:::    -R ReturnVariable
:::
:::       Save the timestamp in ReturnVariable instead of displaying it.
:::       ReturnVariable is unchanged if an error occurs.
:::       Default is empty, meaning print to screen.
:::
:::    -WKD "Abbreviated day of week list"
:::
:::       Override the default day abbreviations with a space delimited,
:::       quoted list, starting with Sun.
:::       Default is mixed case, 3 character English day abbreviations.
:::
:::    -WEEKDAY "Day of week list"
:::
:::       Override the default day names with a space delimited, quoted list,
:::       starting with Sunday.
:::       Default is mixed case English day names.
:::
:::    -MTH "Abbreviated month list"
:::
:::       Override the default month abbreviations with a space delimited,
:::       quoted list, starting with Jan.
:::       Default is mixed case, 3 character English month abbreviations.
:::
:::    -MONTH "Month list"
:::
:::       Override the default month names with a space delimited, quoted list,
:::       starting with January.
:::       Default is mixed case English month names.
:::
:::
:::  GetTimestamp.bat was written by Dave Benham and originally posted at
:::  http://www.dostips.com/forum/viewtopic.php?f=3&t=4847
:::

============= :Batch portion ===========
@echo off
setlocal enableDelayedExpansion

:: Define options
set ^"options=^
 -?:^
 -??:^
 -v:^
 -u:^
 -z:""^
 -f:"{ISO-TS}"^
 -d:""^
 -oy:""^
 -om:""^
 -od:""^
 -oh:""^
 -on:""^
 -os:""^
 -of:""^
 -r:""^
 -wkd:"Sun Mon Tue Wed Thu Fri Sat"^
 -weekday:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday"^
 -mth:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"^
 -month:"January February March April May June July August September October November December"^"

:: Set default option values
for %%O in (%options%) do for /f "tokens=1,* delims=:" %%A in ("%%O") do (
  if defined GetTimestamp%%A (set "%%A=!GetTimestamp%%A!") else set "%%A=%%~B"
)
set "-?="
set "-??="

:: Get options
:loop
if not "%~1"=="" (
  set "arg=%~1"
  if "!arg:~0,1!" equ "/" set "arg=-!arg:~1!"
  for /f delims^=^ eol^= %%A in ("!arg!") do set "test=!options:*%%A:=! "
  if "!test!"=="!options! " (
      >&2 echo Error: Invalid option %~1. Use %~nx0 -? to get help.
      exit /b 1
  ) else if "!test:~0,1!"==" " (
      set "!arg!=1"
      if /i "!arg!" equ "-U" set "-z="
  ) else (
      set "!arg!=%~2"
      shift /1
  )
  shift /1
  goto :loop
)
if defined -z set "-u=1"
if defined -r set "%-r%="

:: Display paged help
if defined -?? (
  (for /f "delims=: tokens=*" %%A in ('findstr "^:::" "%~f0"') do @echo(%%A)|more /e
  exit /b 0
) 2>nul

:: Display help
if defined -? (
  for /f "delims=: tokens=*" %%A in ('findstr "^:::" "%~f0"') do echo(%%A
  exit /b 0
)

:: Display version
if defined -v (
  for /f "tokens=* delims=:" %%A in ('findstr "^::getTimestamp\.bat" "%~f0"') do @echo(%%A
  exit /b 0
)

:: Execute the JScript script and return the result
for /f "delims=" %%A in ('cscript //E:JScript //nologo "%~f0"') do (
  endlocal
  if "%-R%" neq "" (set "%-R%=%%A") else (echo(%%A)
  exit /b 0
)
exit /b 1;


************ JScript portion ***********/
var env  = WScript.CreateObject("WScript.Shell").Environment("Process"),
    utc  = env('-U'),
    wkd     = env('-WKD').split(' '),
    weekday = env('-WEEKDAY').split(' '),
    mth     = env('-MTH').split(' '),
    month   = env('-MONTH').split(' '),
    stderr  = WScript.StdErr,
    y,m,d,w,h,h12,n,s,f,u,z,zs,za,
    pc=':', pd='-', pp='.', p2='00', p3='000', p4='0000';

if (wkd.length!=7)     badOp('-WKD');
if (weekday.length!=7) badOp('-WEEKDAY');
if (mth.length!=12)    badOp('-MTH');
if (month.length!=12)  badOp('-MONTH');

try {
  var dt = eval('new Date('+env('-D')+')');
} catch(e) {
} finally {
  if (isNaN(dt)) badOp('-D');
}

if (env('-OY')) dt.setFullYear(     dt.getFullYear()    +getNum('-OY') );
if (env('-OM')) dt.setMonth(        dt.getMonth()       +getNum('-OM') );
if (env('-OD')) dt.setDate(         dt.getDate()        +getNum('-OD') );
if (env('-OH')) dt.setHours(        dt.getHours()       +getNum('-OH') );
if (env('-ON')) dt.setMinutes(      dt.getMinutes()     +getNum('-ON') );
if (env('-OS')) dt.setSeconds(      dt.getSeconds()     +getNum('-OS') );
if (env('-OF')) dt.setMilliseconds( dt.getMilliseconds()+getNum('-OF') );
if (env('-Z'))  dt.setMinutes(      dt.getMinutes()  +(z=getNum('-Z')) );

y = utc ? dt.getUTCFullYear(): dt.getFullYear();
m = utc ? dt.getUTCMonth()   : dt.getMonth();
d = utc ? dt.getUTCDate()    : dt.getDate();
w = utc ? dt.getUTCDay()     : dt.getDay();
h = utc ? dt.getUTCHours()   : dt.getHours();
n = utc ? dt.getUTCMinutes() : dt.getMinutes();
s = utc ? dt.getUTCSeconds() : dt.getSeconds();
f = utc ? dt.getUTCMilliseconds() : dt.getMilliseconds();
u = dt.getTime();

h12 = h%12;
if (!h12) h12=12;

if (z==undefined) if (utc) z=0; else z=-dt.getTimezoneOffset();
zs = z<0 ? '-' : '+';
za = Math.abs(z);

WScript.echo( env('-F').replace( /\{(.*?)\}/gi, repl ) );
WScript.Quit(0);

function lpad( val, pad ) {
  var rtn=val.toString();
  return (rtn.length<pad.length) ? (pad+rtn).slice(-pad.length) : val;
}

function getNum( v ) {
  var rtn;
  try {
    rtn = Number(eval(env(v)));
  } catch(e) {
  } finally {
    if (isNaN(rtn-rtn)) badOp(v);
    return rtn;
  }
}

function badOp(option) {
  stderr.WriteLine('Error: Invalid '+option+' value');
  WScript.Quit(1);
}

function trunc( n ) { return Math[n>0?"floor":"ceil"](n); }

function repl($0,$1) {
  switch ($1.toUpperCase()) {
    case 'YYYY' : return lpad(y,p4);
    case 'YY'   : return (p2+y.toString()).slice(-2);
    case 'Y'    : return y.toString();
    case 'MM'   : return lpad(m+1,p2);
    case 'M'    : return (m+1).toString();
    case 'DD'   : return lpad(d,p2);
    case 'D'    : return d.toString();
    case 'W'    : return w.toString();
    case 'DY'   : return trunc(((new Date(y,m,d)).getTime()-(new Date(y,0,0)).getTime())/86400000).toString();
    case 'DDY'  : return lpad( trunc(((new Date(y,m,d)).getTime()-(new Date(y,0,0)).getTime())/86400000), p3);
    case 'HH'   : return lpad(h,p2);
    case 'H'    : return h.toString();
    case 'HH12' : return lpad(h12,p2);
    case 'H12'  : return h12.toString();
    case 'NN'   : return lpad(n,p2);
    case 'N'    : return n.toString();
    case 'SS'   : return lpad(s,p2);
    case 'S'    : return s.toString();
    case 'FFF'  : return lpad(f,p3);
    case 'F'    : return f.toString();
    case 'AM'   : return h>=12 ? 'PM' : 'AM';
    case 'PM'   : return h>=12 ? 'pm' : 'am';
    case 'UMS'  : return u.toString();
    case 'USD'  : return (u/1000).toString();
    case 'UMD'  : return (u/1000/60).toString();
    case 'UHD'  : return (u/1000/60/60).toString();
    case 'UDD'  : return (u/1000/60/60/24).toString();
    case 'U'    : return trunc(u/1000).toString();
    case 'US'   : return trunc(u/1000).toString();
    case 'UM'   : return trunc(u/1000/60).toString();
    case 'UH'   : return trunc(u/1000/60/60).toString();
    case 'UD'   : return trunc(u/1000/60/60/24).toString();
    case 'ZZZZ' : return zs+lpad(za,p3);
    case 'Z'    : return z.toString();
    case 'ZS'   : return zs;
    case 'ZH'   : return lpad(trunc(za/60),p2);
    case 'ZM'   : return lpad(za%60,p2);
    case 'TZ'   : return zs+lpad(trunc(za/60),p2)+':'+lpad(za%60,p2);
    case 'ISOTS'  : return ''+lpad(y,p4)+lpad(m+1,p2)+lpad(d,p2)+'T'+lpad(h,p2)+lpad(n,p2)+lpad(s,p2)+pp+lpad(f,p3)+zs+lpad(trunc(za/60),p2)+lpad(za%60,p2);
    case 'ISODT'  : return ''+lpad(y,p4)+lpad(m+1,p2)+lpad(d,p2);
    case 'ISOTM'  : return ''+lpad(h,p2)+lpad(n,p2)+lpad(s,p2)+pp+lpad(f,p3);
    case 'ISOTZ'  : return ''+zs+lpad(trunc(za/60),p2)+lpad(za%60,p2);
    case 'ISO-TS' : return ''+lpad(y,p4)+pd+lpad(m+1,p2)+pd+lpad(d,p2)+'T'+lpad(h,p2)+pc+lpad(n,p2)+pc+lpad(s,p2)+pp+lpad(f,p3)+zs+lpad(trunc(za/60),p2)+pc+lpad(za%60,p2);
    case 'ISO-DT' : return ''+lpad(y,p4)+pd+lpad(m+1,p2)+pd+lpad(d,p2);
    case 'ISO-TM' : return ''+lpad(h,p2)+pc+lpad(n,p2)+pc+lpad(s,p2)+pp+lpad(f,p3);
    case 'ISO-TZ' : return ''+zs+lpad(trunc(za/60),p2)+pc+lpad(za%60,p2);
    case 'WEEKDAY': return weekday[w];
    case 'WKD'    : return wkd[w];
    case 'MONTH'  : return month[m];
    case 'MTH'    : return mth[m];
    case '{'      : return $1;
    default       : return $0;
  }
}


Dave Benham

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: getTimestamp.bat for time and date processing

#29 Post by foxidrive » 13 Jul 2015 05:49

Thanks for your updates Dave. :thumbsup:

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: getTimestamp.bat for time and date processing

#30 Post by dbenham » 27 Nov 2015 21:22

I've been pretty much off the grid for a few months, concentrating on work and music.

But here is a new version 2.4 of getTimeStamp.bat

I reorganized the documentation a bit, and added some new examples for the /D option.

New Features:

1) New formats to specify comma or period as decimal point in ISO 8601 time values:
These are just a convenience, since they could be constructed from component parts.

Code: Select all

{ISO-TM.}  hh:mm:ss.fff  (same as {ISO-TM})
{ISO-TM,}  hh:mm:ss,fff
{ISOTM.}   hhmmss.fff    (same as {ISOTM})
{ISOTM,}   hhmmss,fff
{ISO-TS.}  YYYY-MM-DDThh:mm:ss.fff+hh:mm  (same as {ISO-TS})
{ISO-TS,}  YYYY-MM-DDThh:mm:ss,fff+hh:mm
{ISOTS.}   YYYYMMDDThhmmss.fff+hhmm       (same as {ISOTS})
{ISOTS,}   YYYYMMDDThhmmss,fff+hhmm


2) ISO 8601 Week Dates
There are 52 or 53 full weeks in every year.
The week numbering year varies from the normal calendar year around Jan 1.
- Dec 29, 30, or 31 may belong to the next Jan year
- Jan 01, 02, or 03 may belong to the prior Dec year

Code: Select all

{ISOWY}   yyyy = Week numbering year
{ISOWK}   ww = Week Number
{ISOWD}   d = Day of Week (1=Monday, 7=Sunday)
{ISO-DTW} yyyy-Www-d
{ISODT2}  yyyyWwwd


3) ISO 8601 Ordinal Dates
The component parts were already available, so these are just a convenience.

Code: Select all

{ISO-DTO}  YYYY-DDD
{ISODTO}   YYYYDDD


Here is the code:

Code: Select all

@if (@X)==(@Y) @end  /* harmless hybrid line that begins a JScript comment
@goto :batch
::
::getTimestamp.bat version 2.4 by Dave Benham
::
::  Release History:
::    2.4 2015-11-27 - Added formats to support comma as decimal mark in
::                     ISO 8601 time and timestamp formats.
::                     Added formats to support ISO 8601 week dates
::                     and ordinal dates.
::                     Rearranged documentation, and added examples for
::                     base date specified as a list of numeric values.
::    2.3 2015-07-11 - Added {ISO-xx}, {ISOxx}, {DY} and {DDY} formats
::                     Added -?? (paged help) option
::                     Allow user defined default option values by defining
::                     variables of the form "GetTimestamp-OPTION=VALUE"
::    2.2 2014-12-03 - Doc fix: -R ReturnVariable is unchanged if err occurs
::    2.1 2014-12-03 - Added GOTO at top to increase performance (32% faster)
::    2.0 2014-12-02 - Major rewrite: most code now in JScript (25% faster)
::                     Better error handling
::                     May now use /Option or -Option
::                     Added -V option
::                     Added {{} format value to enable unambiguous { literal
::    1.1 ????-??-?? - Added -Z option and obscure bug fixes
::    1.0 2013-07-17 - Initial release
::
::============ Documentation ===========
:::
:::getTimestamp  [-option [value]]...
:::
:::  Displays a formatted timestamp. Defaults to the current local date
:::  and time using an ISO 8601 format with milliseconds, time zone
:::  and punctuation, using period as a decimal mark.
:::
:::  Returned ERRORLEVEL is 0 upon success, 1 if failure.
:::
:::  Options may be prefaced with - or /
:::
:::  All options have default values. The default value can be overridden by
:::  defining an evironment variable of the form "GetTimestamp-OPTION=VALUE".
:::  For example, upper case English weekday abbreviations can be specified as
:::  the default by defining "GetTimestamp-WKD=SUN MON TUE WED THU FRI SAT".
:::
:::  Command line option values take precedence, followed by environment variable
:::  defaults, followed by built in defaults.
:::
:::  The following options are all case insensitive:
:::
:::    -?  : Prints this documentation for getTimestamp
:::
:::    -?? : Prints this documentation with pagination via MORE
:::
:::    -V  : Prints the version of getTimeStamp
:::
:::    -D DateSpec
:::
:::       Specify the base date and time.
:::       Default value is current local date and time.
:::       The DateSpec supports many formats:
:::
:::         ""    (no value)
:::
:::           Current date and time - the default
:::
:::         milliseconds
:::
:::           A JScript numeric expression that represents the number of
:::           milliseconds since 1970-01-01 00:00:00 UTC.
:::           Decimal values are truncated.
:::           Negative values represent dates prior to 1970-01-01.
:::
:::         "'Date [Time] [TimeZone]'"
:::
:::           A string representation of the date and time. The date information
:::           is required, the time and time zone are optional. Missing time info
:::           is assumed to be 0 (midnight). Missing time zone info is assumed to
:::           be local time zone.
:::
:::           The Date, Time, and TimeZone information can be represented as any
:::           string that is accepted by the JScript Date.Parse() method.
:::           There are many formatting options. Documentation is available at:
:::           http://msdn.microsoft.com/en-us/library/k4w173wk(v=vs.84).aspx
:::
:::           Examples of equivalent representations of Midnight on January 4,
:::           2013 assuming local time zone is U.S Eastern Standard Time (EST):
:::
:::             '1-4-2013'                    Defaults to local time zone
:::             "'January 4, 2013 EST'"       Explicit Eastern Std Time (US)
:::             "'2013/1/4 -05'"              Explicit Eastern Std Time (US)
:::             "'Jan 3 2013 23: CST'"        Central Standard Time (US)
:::             "'2013 3 Jan 9:00 pm -0800'"  Pacific Standard Time (US)
:::             "'01/04/2013 05:00:00 UTC'"   Universal Coordinated Time
:::             "'1/4/2013 05:30 +0530'"      India Standard Time
:::
:::         "year, month[, day[, hour[, minute[, second[, millisecond]]]]]"
:::
:::           A comma delimited list of numeric JScript expressions representing
:::           various components of date and time. Year and month are required,
:::           the rest are optional. Missing values are treated as 0.
:::           Decimal values are truncated. A 0 month represents January.
:::           A 1 day represents the first day of the month. A 0 day represents
:::           the last day of the prior month. The date/time value is always
:::           in local time. There is no mechanism to specify a time zone.
:::
:::           Examples: (all in local time)
:::             "2012,0,1,12,45,3,121"  12:45:03.121 on Jan 1, 2012
:::             "2012,0,1,12"           Noon on Jan 1, 2012
:::             "2012,1,1"              Midnight on Feb 1, 2012
:::             "2012,2,0"              Midnight on Feb 29, 2012 (last day of Feb)
:::             "2012,2"                Midnight on Feb 29, 2012 (last day of Feb)
:::
:::           The ability to use JScript expressions makes it convenient to do
:::           date and time offset computations in a very compact form.
:::
:::           For example, starting with:
:::             "2015,8,7,14,5"        Sep 7, 2015 at 14:05:00
:::
:::           It is simple to subtract 30 days and 30 minutes from the above:
:::             "2015,8,7-30,14,5-30"  Aug 8, 2015 at 13:35:00
:::
:::    -U  : Returns a UTC timestamp instead of local timestamp.
:::          Default is a local timestamp.
:::
:::    -Z TimeZoneMinuteOffset
:::
:::       Returns the timestamp using the specified time zone offset.
:::       TimeZoneMinuteOffset is a JScript numeric expression that
:::       represents the number of minutes offset from UTC.
:::       Decimal values are truncated.
:::       Default is empty, meaning local timezone.
:::
:::    -OY YearOffset
:::
:::       Specify the number of years to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OM MonthOffset
:::
:::       Specify the number of months to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OD DayOffset
:::
:::       Specify the number of days to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OH HourOffset
:::
:::       Specify the number of hours to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -ON MinuteOffset
:::
:::       Specify the number of minutes to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OS SecondOffset
:::
:::       Specify the number of seconds to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -OF MillisecondOffset
:::
:::       Specify the number of milliseconds to offset the base date/time.
:::       The JScript numeric expression is truncated to an integral number.
:::       Default is 0
:::
:::    -F FormatString
:::
:::       Specify the timestamp format.
:::       Default is "{ISO-TS.}"
:::       Strings within braces are dynamic components.
:::       All other strings are literals.
:::       Available components (case insensitive) are:
:::
:::         {YYYY}  4 digit year, zero padded
:::
:::         {YY}    2 digit year, zero padded
:::
:::         {Y}     year without zero padding
:::
:::         {MONTH} month name, as preferentially specified by:
:::                    1) -MONTH option
:::                    2) GetTimestamp-MONTH environment variable
:::                    3) Mixed case, English month names
:::
:::         {MTH}   month abbreviation, as preferentially specified by:
:::                    1) -MTH option
:::                    2) GetTimestamp-MTH environment variable
:::                    3) Mixed case, English month abbreviations
:::
:::         {MM}    2 digit month number, zero padded
:::
:::         {M}     month number without zero padding
:::
:::         {WEEKDAY} day of week name, as preferentially specified by:
:::                    1) -WEEKDAY option
:::                    2) GetTimestamp-WEEKDAY environment variable
:::                    3) Mixed case, English day names
:::
:::         {WKD}   day of week abbreviation, as preferentially specified by:
:::                    1) -WKD option
:::                    2) GetTimestamp-WKD environment variable
:::                    3) Mixed case, English day abbreviations
:::
:::         {W}     day of week number: 0=Sunday, 6=Saturday
:::
:::         {DD}    2 digit day of month number, zero padded
:::
:::         {D}     day of month number, without zero padding
:::
:::         {DDY}   3 digit day of year number, zero padded
:::
:::         {DY}    day of year number, without zero padding
:::
:::         {HH}    2 digit hours, 24 hour format, zero padded
:::
:::         {H}     hours, 24 hour format without zero padding
:::
:::         {HH12}  2 digit hours, 12 hour format, zero padded
:::
:::         {H12}   hours, 12 hour format without zero padding
:::
:::         {NN}    2 digit minutes, zero padded
:::
:::         {N}     minutes without padding
:::
:::         {SS}    2 digit seconds, zero padded
:::
:::         {S}     seconds without padding
:::
:::         {FFF}   3 digit milliseconds, zero padded
:::
:::         {F}     milliseconds without padding
:::
:::         {AM}    AM or PM in upper case
:::
:::         {PM}    am or pm in lower case
:::
:::         {ZZZZ}  timezone expressed as minutes offset from UTC,
:::                 zero padded to 3 digits with sign
:::
:::         {Z}     timzone expressed as minutes offset from UTC without padding
:::
:::         {ZS}    ISO 8601 timezone sign
:::
:::         {ZH}    ISO 8601 timezone hours (no sign)
:::
:::         {ZM}    ISO 8601 timezone minutes (no sign)
:::
:::         {TZ}    ISO 8601 timezone in +/-hh:mm format
:::
:::         {ISOTS}  same as {ISOTS.}
:::
:::         {ISOTS.} YYYYMMDDThhmmss.fff+hhss
:::                  Compressed ISO 8601 date/time (timestamp) with milliseconds
:::                  and time zone, using . as decimal mark
:::
:::         {ISOTS,} YYYYMMDDThhmmss,fff+hhss
:::                  Compressed ISO 8601 date/time (timestamp) with milliseconds
:::                  and time zone, using , as decimal mark
:::
:::         {ISODT}  YYYYMMDD
:::                  Compressed ISO 8601 date format
:::
:::         {ISOTM}  same as {ISOTM.}
:::
:::         {ISOTM.} hhmmss.fff
:::                  Compressed ISO 8601 time format with milliseconds,
:::                  using . as decimal mark
:::
:::         {ISOTM,} hhmmss,fff
:::                  Compressed ISO 8601 time format with milliseconds,
:::                  using , as decimal mark
:::
:::         {ISOTZ}  +hhmm
:::                  Compressed ISO 8601 timezone format
:::
:::         {ISOWY}  yyyy
:::                  ISO 8601 week numbering year
:::                  Dec 29, 30, or 31 may belong to the next Jan year
:::                  Jan 01, 02, or 03 may belong to the prior Dec year
:::
:::         {ISOWK}  ww
:::                  ISO 8601 week number
:::                  Week 01 is the week with the year's first Thursday
:::
:::         {ISOWD}  d
:::                  ISO 8601 day of week: 1=Monday, 7=Sunday
:::
:::         {ISODTW} yyyyWwwd
:::                  Compressed ISO 8601 week date format
:::
:::         {ISODTO} YYYYDDD
:::                  Compressed ISO 8601 ordinal date format
:::
:::         {ISO-TS} same as {ISO-TS.}
:::
:::         {ISO-TS.} YYYY-MM-DDThh:mm:ss.fff+hh:ss
:::                  ISO 8601 date/time (timestamp) with milliseconds and time zone
:::                  using . as decimal mark
:::
:::         {ISO-TS,} YYYY-MM-DDThh:mm:ss,fff+hh:ss
:::                  ISO 8601 date/time (timestamp) with milliseconds and time zone
:::                  using , as decimal mark
:::
:::         {ISO-DT} YYYY-MM-DD
:::                  ISO 8601 date format
:::
:::         {ISO-TM} same as {ISO-TM.}
:::
:::         {ISO-TM.} hh:mm:ss.fff
:::                  ISO 8601 time format with milliseconds,
:::                  using . as decimal mark
:::
:::         {ISO-TM,} hh:mm:ss,fff
:::                  ISO 8601 time format with milliseconds,
:::                  using , as decimal mark
:::
:::         {ISO-TZ} +hh:mm
:::                  ISO 8601 timezone  (same as {TZ})
:::
:::         {ISO-DTW} yyyy-Www-d
:::                  ISO 8601 week date format
:::
:::         {ISO-DTO} YYYY-DDD
:::                  ISO 8601 ordinal date format
:::
:::         {UMS}   Milliseconds since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {U}     Same as {US}
:::
:::         {US}    Seconds since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UM}    Minutes since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UH}    Hours since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UD}    Days since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {USD}   Decimal seconds since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UMD}   Decimal minutes since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UHD}   Decimal hours since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {UDD}   Decimal days since 1970-01-01 00:00:00.000 UTC.
:::                 Negative numbers represent days prior to 1970-01-01.
:::                 This value is unaffected by the -U option.
:::                 This value should not be used with the -Z option
:::
:::         {{}     A { character
:::
:::    -R ReturnVariable
:::
:::       Save the timestamp in ReturnVariable instead of displaying it.
:::       ReturnVariable is unchanged if an error occurs.
:::       Default is empty, meaning print to screen.
:::
:::    -WKD "Abbreviated day of week list"
:::
:::       Override the default day abbreviations with a space delimited,
:::       quoted list, starting with Sun.
:::       Default is mixed case, 3 character English day abbreviations.
:::
:::    -WEEKDAY "Day of week list"
:::
:::       Override the default day names with a space delimited, quoted list,
:::       starting with Sunday.
:::       Default is mixed case English day names.
:::
:::    -MTH "Abbreviated month list"
:::
:::       Override the default month abbreviations with a space delimited,
:::       quoted list, starting with Jan.
:::       Default is mixed case, 3 character English month abbreviations.
:::
:::    -MONTH "Month list"
:::
:::       Override the default month names with a space delimited, quoted list,
:::       starting with January.
:::       Default is mixed case English month names.
:::
:::
:::  GetTimestamp.bat was written by Dave Benham and originally posted at
:::  http://www.dostips.com/forum/viewtopic.php?f=3&t=4847
:::

============= :Batch portion ===========
@echo off
setlocal enableDelayedExpansion

:: Define options
set ^"options=^
 -?:^
 -??:^
 -v:^
 -u:^
 -z:""^
 -f:"{ISO-TS}"^
 -d:""^
 -oy:""^
 -om:""^
 -od:""^
 -oh:""^
 -on:""^
 -os:""^
 -of:""^
 -r:""^
 -wkd:"Sun Mon Tue Wed Thu Fri Sat"^
 -weekday:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday"^
 -mth:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"^
 -month:"January February March April May June July August September October November December"^"

:: Set default option values
for %%O in (%options%) do for /f "tokens=1,* delims=:" %%A in ("%%O") do (
  if defined GetTimestamp%%A (set "%%A=!GetTimestamp%%A!") else set "%%A=%%~B"
)
set "-?="
set "-??="

:: Get options
:loop
if not "%~1"=="" (
  set "arg=%~1"
  if "!arg:~0,1!" equ "/" set "arg=-!arg:~1!"
  for /f delims^=^ eol^= %%A in ("!arg!") do set "test=!options:*%%A:=! "
  if "!test!"=="!options! " (
      >&2 echo Error: Invalid option %~1. Use %~nx0 -? to get help.
      exit /b 1
  ) else if "!test:~0,1!"==" " (
      set "!arg!=1"
      if /i "!arg!" equ "-U" set "-z="
  ) else (
      set "!arg!=%~2"
      shift /1
  )
  shift /1
  goto :loop
)
if defined -z set "-u=1"
if defined -r set "%-r%="

:: Display paged help
if defined -?? (
  (for /f "delims=: tokens=*" %%A in ('findstr "^:::" "%~f0"') do @echo(%%A)|more /e
  exit /b 0
) 2>nul

:: Display help
if defined -? (
  for /f "delims=: tokens=*" %%A in ('findstr "^:::" "%~f0"') do echo(%%A
  exit /b 0
)

:: Display version
if defined -v (
  for /f "tokens=* delims=:" %%A in ('findstr "^::getTimestamp\.bat" "%~f0"') do @echo(%%A
  exit /b 0
)

:: Execute the JScript script and return the result
for /f "delims=" %%A in ('cscript //E:JScript //nologo "%~f0"') do (
  endlocal
  if "%-R%" neq "" (set "%-R%=%%A") else (echo(%%A)
  exit /b 0
)
exit /b 1;


************ JScript portion ***********/
var env  = WScript.CreateObject("WScript.Shell").Environment("Process"),
    utc  = env('-U'),
    wkd     = env('-WKD').split(' '),
    weekday = env('-WEEKDAY').split(' '),
    mth     = env('-MTH').split(' '),
    month   = env('-MONTH').split(' '),
    stderr  = WScript.StdErr,
    y,m,d,w,h,h12,n,s,f,u,z,zs,za,
    pc=':', pcm=',', pd='-', pp='.', p2='00', p3='000', p4='0000';

if (wkd.length!=7)     badOp('-WKD');
if (weekday.length!=7) badOp('-WEEKDAY');
if (mth.length!=12)    badOp('-MTH');
if (month.length!=12)  badOp('-MONTH');

try {
  var dt = eval('new Date('+env('-D')+')');
} catch(e) {
} finally {
  if (isNaN(dt)) badOp('-D');
}

if (env('-OY')) dt.setFullYear(     dt.getFullYear()    +getNum('-OY') );
if (env('-OM')) dt.setMonth(        dt.getMonth()       +getNum('-OM') );
if (env('-OD')) dt.setDate(         dt.getDate()        +getNum('-OD') );
if (env('-OH')) dt.setHours(        dt.getHours()       +getNum('-OH') );
if (env('-ON')) dt.setMinutes(      dt.getMinutes()     +getNum('-ON') );
if (env('-OS')) dt.setSeconds(      dt.getSeconds()     +getNum('-OS') );
if (env('-OF')) dt.setMilliseconds( dt.getMilliseconds()+getNum('-OF') );
if (env('-Z'))  dt.setMinutes(      dt.getMinutes()  +(z=getNum('-Z')) );

y = utc ? dt.getUTCFullYear(): dt.getFullYear();
m = utc ? dt.getUTCMonth()   : dt.getMonth();
d = utc ? dt.getUTCDate()    : dt.getDate();
w = utc ? dt.getUTCDay()     : dt.getDay();
h = utc ? dt.getUTCHours()   : dt.getHours();
n = utc ? dt.getUTCMinutes() : dt.getMinutes();
s = utc ? dt.getUTCSeconds() : dt.getSeconds();
f = utc ? dt.getUTCMilliseconds() : dt.getMilliseconds();
u = dt.getTime();

h12 = h%12;
if (!h12) h12=12;

if (z==undefined) if (utc) z=0; else z=-dt.getTimezoneOffset();
zs = z<0 ? '-' : '+';
za = Math.abs(z);

WScript.echo( env('-F').replace( /\{(.*?)\}/gi, repl ) );
WScript.Quit(0);

function lpad( val, pad ) {
  var rtn=val.toString();
  return (rtn.length<pad.length) ? (pad+rtn).slice(-pad.length) : val;
}

function getNum( v ) {
  var rtn;
  try {
    rtn = Number(eval(env(v)));
  } catch(e) {
  } finally {
    if (isNaN(rtn-rtn)) badOp(v);
    return rtn;
  }
}

function badOp(option) {
  stderr.WriteLine('Error: Invalid '+option+' value');
  WScript.Quit(1);
}

function trunc( n ) { return Math[n>0?"floor":"ceil"](n); }

function weekNum(dt) {
   var dt2 = new Date(dt.valueOf());
   var day = (dt.getDay()+6)%7;
   dt2.setDate(dt2.getDate()-day+3);
   var now = dt2.valueOf();
   dt2.setMonth(0, 1);
   if (dt2.getDay() != 4) {
      dt2.setMonth( 0, (11-dt2.getDay())%7 + 1 );
   }
   return 1 + Math.ceil((now-dt2.valueOf())/604800000);
}

function weekYr(dt) {
   var dt2 = new Date(dt.valueOf());
   dt2.setDate(dt2.getDate()+3-(dt.getDay()+6)%7);
   return dt2.getFullYear();
}

function repl($0,$1) {
  switch ($1.toUpperCase()) {
    case 'YYYY' : return lpad(y,p4);
    case 'YY'   : return (p2+y.toString()).slice(-2);
    case 'Y'    : return y.toString();
    case 'MM'   : return lpad(m+1,p2);
    case 'M'    : return (m+1).toString();
    case 'DD'   : return lpad(d,p2);
    case 'D'    : return d.toString();
    case 'W'    : return w.toString();
    case 'DY'   : return trunc(((new Date(y,m,d)).getTime()-(new Date(y,0,0)).getTime())/86400000).toString();
    case 'DDY'  : return lpad( trunc(((new Date(y,m,d)).getTime()-(new Date(y,0,0)).getTime())/86400000), p3);
    case 'HH'   : return lpad(h,p2);
    case 'H'    : return h.toString();
    case 'HH12' : return lpad(h12,p2);
    case 'H12'  : return h12.toString();
    case 'NN'   : return lpad(n,p2);
    case 'N'    : return n.toString();
    case 'SS'   : return lpad(s,p2);
    case 'S'    : return s.toString();
    case 'FFF'  : return lpad(f,p3);
    case 'F'    : return f.toString();
    case 'AM'   : return h>=12 ? 'PM' : 'AM';
    case 'PM'   : return h>=12 ? 'pm' : 'am';
    case 'UMS'  : return u.toString();
    case 'USD'  : return (u/1000).toString();
    case 'UMD'  : return (u/1000/60).toString();
    case 'UHD'  : return (u/1000/60/60).toString();
    case 'UDD'  : return (u/1000/60/60/24).toString();
    case 'U'    :
    case 'US'   : return trunc(u/1000).toString();
    case 'UM'   : return trunc(u/1000/60).toString();
    case 'UH'   : return trunc(u/1000/60/60).toString();
    case 'UD'   : return trunc(u/1000/60/60/24).toString();
    case 'ZZZZ' : return zs+lpad(za,p3);
    case 'Z'    : return z.toString();
    case 'ZS'   : return zs;
    case 'ZH'   : return lpad(trunc(za/60),p2);
    case 'ZM'   : return lpad(za%60,p2);
    case 'TZ'   :
    case 'ISO-TZ' : return ''+zs+lpad(trunc(za/60),p2)+pc+lpad(za%60,p2);
    case 'ISOTS'  :
    case 'ISOTS.' : return ''+lpad(y,p4)+lpad(m+1,p2)+lpad(d,p2)+'T'+lpad(h,p2)+lpad(n,p2)+lpad(s,p2)+pp+lpad(f,p3)+zs+lpad(trunc(za/60),p2)+lpad(za%60,p2);
    case 'ISOTS,' : return ''+lpad(y,p4)+lpad(m+1,p2)+lpad(d,p2)+'T'+lpad(h,p2)+lpad(n,p2)+lpad(s,p2)+pcm+lpad(f,p3)+zs+lpad(trunc(za/60),p2)+lpad(za%60,p2);
    case 'ISODT'  : return ''+lpad(y,p4)+lpad(m+1,p2)+lpad(d,p2);
    case 'ISOTM'  :
    case 'ISOTM.' : return ''+lpad(h,p2)+lpad(n,p2)+lpad(s,p2)+pp+lpad(f,p3);
    case 'ISOTM,' : return ''+lpad(h,p2)+lpad(n,p2)+lpad(s,p2)+pcm+lpad(f,p3);
    case 'ISOTZ'  : return ''+zs+lpad(trunc(za/60),p2)+lpad(za%60,p2);
    case 'ISO-TS' :
    case 'ISO-TS.': return ''+lpad(y,p4)+pd+lpad(m+1,p2)+pd+lpad(d,p2)+'T'+lpad(h,p2)+pc+lpad(n,p2)+pc+lpad(s,p2)+pp+lpad(f,p3)+zs+lpad(trunc(za/60),p2)+pc+lpad(za%60,p2);
    case 'ISO-TS,': return ''+lpad(y,p4)+pd+lpad(m+1,p2)+pd+lpad(d,p2)+'T'+lpad(h,p2)+pc+lpad(n,p2)+pc+lpad(s,p2)+pcm+lpad(f,p3)+zs+lpad(trunc(za/60),p2)+pc+lpad(za%60,p2);
    case 'ISO-DT' : return ''+lpad(y,p4)+pd+lpad(m+1,p2)+pd+lpad(d,p2);
    case 'ISO-TM' :
    case 'ISO-TM.': return ''+lpad(h,p2)+pc+lpad(n,p2)+pc+lpad(s,p2)+pp+lpad(f,p3);
    case 'ISO-TM,': return ''+lpad(h,p2)+pc+lpad(n,p2)+pc+lpad(s,p2)+pcm+lpad(f,p3);
    case 'ISOWY'  : return ''+lpad(weekYr(dt),p4);
    case 'ISOWK'  : return ''+lpad(weekNum(dt),p2);
    case 'ISOWD'  : return ''+((w+6)%7+1);
    case 'ISODTW' : return ''+lpad(weekYr(dt),p4)+'W'+lpad(weekNum(dt),p2)+((w+6)%7+1);
    case 'ISODTO' : return ''+lpad(y,p4)+lpad( trunc(((new Date(y,m,d)).getTime()-(new Date(y,0,0)).getTime())/86400000), p3);
    case 'ISO-DTW': return ''+lpad(weekYr(dt),p4)+pd+'W'+lpad(weekNum(dt),p2)+pd+((w+6)%7+1);
    case 'ISO-DTO': return ''+lpad(y,p4)+pd+lpad( trunc(((new Date(y,m,d)).getTime()-(new Date(y,0,0)).getTime())/86400000), p3);
    case 'WEEKDAY': return weekday[w];
    case 'WKD'    : return wkd[w];
    case 'MONTH'  : return month[m];
    case 'MTH'    : return mth[m];
    case '{'      : return $1;
    default       : return $0;
  }
}



Dave Benham

Post Reply