2

I am trying to get images to display in a specific order on as many smartphones as possible without them requiring specific software, and the easiest way to do this is to change the creation times of the images so that the first file alphanumerically is the most recently time stamped and so forth. This process needs to be done on potentially hundreds of images at a time so I cannot do it manually. Is there a tool or method that can automate the process?

1 Answers1

0

Give this batch file below a try.

It will display matching files along with the new timestamp information, but will not (yet) modify the file timestamps.

Save the batch script to a file with the extension .cmd (example: redatefiles.cmd).

It will process all the files in the current (working) folder.

You can run it like this:

    C:\>redatefiles.cmd

If you run it that way, it will use these defaults:

  • Files in the current folder with an extension of .jpg will be processed. All other files will be skipped.
  • The date (not time) of the matching file that is alphabetically first will be used as the date for the generated timestamp for all matching files.
  • The time for the generated timestamp (in 24 hour format) will begin at 23:59:58 for the first matching file.

The time will then decrease by 2 seconds for each file, so the second matching file will be timestamped 23:59:56 then 23:59:54 ... 23:59:00, 23:58:58 ... 23:00:00, 22:59:58, and so on.

If you want to specify a different filemask you can run it like this:

    C:\>redatefiles.cmd .png
or  C:\>redatefiles.cmd *.png
or  C:\>redatefiles.cmd "*.png"

You can also specify multiple filemasks by separating each filemask with a | like this (double quotes are required):

    C:\>redatefiles.cmd ".png|.jpg"
or  C:\>redatefiles.cmd "*.png|*.jpg"

or  C:\>redatefiles.cmd "|.png|.jpg|"
or  C:\>redatefiles.cmd "|*.png|*.jpg|"

If you want to include files that do not have an extension, specify that with a single . (dot) like this:

    C:\>redatefiles.cmd .
or  C:\>redatefiles.cmd "."
or  C:\>redatefiles.cmd ".|.png"
or  C:\>redatefiles.cmd ".png|.|.jpg"


For the filemask, you cannot:

  • specify a name part of the filename,
  • specify wildcards other than a single * as the name part of the filename,
  • specify wildcards in the extension part of the filename.
  • specify *.* as the filemask

For example, these will not work:

    C:\>redatefiles.cmd somefile.png
    C:\>redatefiles.cmd somefile*.png
    C:\>redatefiles.cmd ?.png
    C:\>redatefiles.cmd *.pn*
    C:\>redatefiles.cmd *.*

And, if the time for a file decreases from 00:00:02 to 00:00:00, the time for the next file will be 23:59:58 on the same day. This effectively limits the script to processing a maximum of about 43200 in the same folder.

If any of these restrictions won't work for you, let me know and I will edit the script to allow for it.

Configuration: If you look within the first few lines of the batch script, you will see some lines like this:

rem    set "zzdate=01/01/2013"
rem    set "zzhour24=23"
rem    set "zzminute=59"
rem    set "zzsecond=58"

If you want to configure the batch script to use a different date or starttime, you can specify it here by removing the rem on each of these lines and supplying your desired values like this:

set "zzdate=05/07/2013"
set "zzhour24=10"
set "zzminute=00"
set "zzsecond=00"

Once you have tried this and verified the proper files are selected, and the timestamps are processed as you need, let me know and I will add the code to make the timestamp changes.

Also, please let me know if this is correct:

  1. Your location uses the US date format of MM/DD/YYYY like 04/30/2013
  2. You need to set the Creation time for the files and not the Modification time (or perhaps if you need to set both).
  3. You have installed or can install Microsoft Powershell on your computer.


Here is the batch script.

@echo off

rem    starting from 23:59:58, if there are 43200 files or more, it will not roll to previous day

call :clean

rem    set "zzdate=01/01/2013"
rem    set "zzhour24=23"
rem    set "zzminute=59"
rem    set "zzsecond=58"

rem    *************************

set "zz_1=%~1"
set "zzdateready=0"
set "zztimeready=0"



call :getextlist
echo.
echo Re-dating files matching: "%zzextlist%"
echo.

for /f "usebackq delims=" %%f in (`dir /b /on "*.*"`) do call :work "%%~ff"   "%%~nxf"   "%%~xf"
goto :EOF





:work
rem:work

set "zz_full=%~1"
set "zz_name=%~2"
set "zz_ext=%~3"
if "%zz_ext%."=="." set "zz_ext=."



echo "%zzextlist%"|find /i "|%zz_ext%|">nul
if %errorlevel% NEQ 0 goto :noextmatch



rem    got a target file
if not %zzdateready%%zztimeready% EQU 11 call :settimestamp

rem    echo zzdate =%zzdate%
rem    echo zzmonth=%zzmonth%/%zzday%/%zzyear%
rem    echo zzhour24=%zzhour24%:%zzminute%:%zzsecond%
rem    echo zzhour12=%zzhour12%:%zzminute%:%zzsecond% %zzampm%
rem    echo zz_full=%zz_full%
rem    echo zz_ext=%zz_ext%
echo new timestamp: %zzmonth%/%zzday%/%zzyear% %zzhour24%:%zzminute%:%zzsecond%  (%zzhour12%:%zzminute%:%zzsecond% %zzampm%) for file: %zz_name% 



call :decrementtime
rem    echo next timestamp=%zzmonth%/%zzday%/%zzyear% %zzhour24%:%zzminute%:%zzsecond%  (%zzhour12%:%zzminute%:%zzsecond% %zzampm%)
rem    echo.

goto :EOF





:noextmatch
rem:noextmatch
echo Skipping file: %zz_name%
rem    echo.
goto :EOF




:settimestamp
rem:settimestamp

if "%zzdate%."=="." call :getfiledate
if %zzdateready% EQU 0 call :explodedate
if "%zzhour24%."=="." call :setdefaulttime
if "%zzminute%."=="." call :setdefaulttime
if "%zzsecond%."=="." call :setdefaulttime
if %zztimeready% EQU 0 call :settime12

goto :EOF





:getfiledate
rem:getfiledate

for /f "usebackq delims=" %%g in (`dir "%zz_full%"^|find /i "%zz_name%"`) do set "zzdstring=%%~g"
set "zzdate=%zzdstring:~0,10%"
rem    echo zzdstring=%zzdstring%
set "zzdstring="

goto :EOF





:explodedate
rem:explodedate

set "zzmonth=%zzdate:~0,2%"
set "zzday=%zzdate:~3,2%"
set "zzyear=%zzdate:~6,4%"
set "zzdateready=1"

goto :EOF





:setdefaulttime
rem:setdefaulttime

set "zzhour24=23"
set "zzminute=59"
set "zzsecond=58"

goto :EOF





:settime12
rem:settime12

rem    insure 2 digit times
set "zzhour24=00%zzhour24%"
set "zzminute=00%zzminute%"
set "zzsecond=00%zzsecond%"
set "zzhour24=%zzhour24:~-2%"
set "zzminute=%zzminute:~-2%"
set "zzsecond=%zzsecond:~-2%"

set "zzampm=AM"
set "zzhour12=%zzhour24%"
if %zzhour12% GEQ 12 set "zzampm=PM"
if %zzhour12% GTR 12 set /A zzhour12=%zzhour24%-12
set "zzhour12=0%zzhour12%
set "zzhour12=%zzhour12:~-2%
if "%zzhour12%"=="00" set "zzhour12=12"
set "zztimeready=1"

goto :EOF





:decrementtime
rem:decrementtime

if 1%zzsecond% EQU 100 goto :fixseconds
set /a zzsecond=1%zzsecond%-2
set zzsecond=%zzsecond:~1%
goto :EOF





:fixseconds
rem:fixseconds

rem    zzsecond is 00, set to 58, then check zzminute
set zzsecond=58

if 1%zzminute% EQU 100 goto :fixminutes
set /a zzminute=1%zzminute%-1
set zzminute=%zzminute:~1%
goto :EOF




:fixminutes
rem:fixminutes

rem    zzminute is 00, set to 59, then check zzhourXX
set zzminute=59

if 1%zzhour24% EQU 100 goto :fixhours
set /a zzhour24=1%zzhour24%-1
set /a zzhour12=1%zzhour12%-1
set zzhour24=%zzhour24:~1%
set zzhour12=%zzhour12:~1%

rem    if hour12 just went from 01:00:00 PM to 00:59:58 PM make it 12:59:58 PM
if "%zzhour12%:%zzminute%:%zzsecond% %zzampm%"=="00:59:58 PM" set "zzhour12=12"

rem    if hour12 just went from 12:00:00 PM to 11:59:58 PM make it 11:59:58 AM
if "%zzhour12%:%zzminute%:%zzsecond% %zzampm%"=="11:59:58 PM" set "zzampm=AM"

rem    if hour12 just went from 01:00:00 AM to 00:59:58 AM make it 12:59:58 AM
if "%zzhour12%:%zzminute%:%zzsecond% %zzampm%"=="00:59:58 AM" set "zzhour12=12"

rem    if hour12 just went from 12:00:00 AM to 11:59:58 PM (previous day) it should be handled by :fixhours
goto :EOF





:fixhours
rem:fixhours

rem not adjusting date if hours rolls under 00

set "zzhour24=23"
set "zzminute=59"
set "zzsecond=58"

set "zzampm=AM"
set "zzhour12=%zzhour24%"
if %zzhour12% GEQ 12 set "zzampm=PM"
if %zzhour12% GTR 12 set /A zzhour12=%zzhour24%-12
set "zzhour12=0%zzhour12%
set "zzhour12=%zzhour12:~-2%
if "%zzhour12%"=="00" set "zzhour12=12"


goto :EOF







:getextlist
rem:getextlist

rem    set default of "*.jpg"
set "zzextlist=|.jpg|"

set "zztext=x%zz_1%x"
if "%zztext%"=="xx" goto :EOF

set "zztext=%zztext:~1,-1%"
set "zztemp=%zztext:~0,1%"
if "%zztemp%"=="/" goto :EOF

set "zzextlist=%zztext%"
if "%zztemp%"=="|" set "zzextlist=%zztext:|*=|%"
if "%zztemp%"=="|" goto :EOF
set "zzextlist=|%zztext%|"
set "zzextlist=%zzextlist:|*=|%"
goto :EOF





:clean
rem:clean

set "zzextlist="

set "zzdate="
set "zzmonth="
set "zzday="
set "zzyear="
set "zzdstring="

set "zzhour24="
set "zzminute="
set "zzsecond="

set "zzhour12="
set "zzampm="

set "zzdateready="
set "zztimeready="

set "zz_full="
set "zz_name="
set "zz_ext="

set "zztemp="
set "zztext="
set "zz_1="

goto :EOF



Edit:

Here is the code to modify the file Creation time timestamps formatted as US date, using Microsoft Powershell.

To add the code to modify the file Creation time timestamps to the batch file shown above:

1. Find the line that begins: echo new timestamp.... It looks like this:

echo new timestamp: %zzmonth%/%zzday%/%zzyear% %zzhour24%:%zzminute%:%zzsecond%  (%zzhour12%:%zzminute%:%zzsecond% %zzampm%) for file: %zz_name%

2. Just below that line, insert these three lines:

set "zzpsstamp12=%zzmonth%/%zzday%/%zzyear% %zzhour12%:%zzminute%:%zzsecond% %zzampm%"
set "zzpscmd=(dir \"%zz_full%\").CreationTime=\"%zzpsstamp12%\"
call powershell %zzpscmd%


If this won't work for you, let me know what you need and I'll edit the script for you.

Kevin Fegan
  • 4,997