Changing Filename date format to yyyy-mm-dd Issues

Hello,

I'm in the process of modifying thousands of files, all with different date formats (some periods, some without spaces, and some with fewer digits) and I'm trying to make them all named with the following YYYY-MM-DD.

I have found the following forum below, but I'm running into issues when the original filename doesn't have 8 digits or when the dates don't have spaces, such as MMDDYY. If the digits are less than 8, for example 1 digit for the month or day, or sometimes 2 digits for the year, its extremely difficult to modify.

A single regex is probably next to impossible. You'll need few iterations. Start with the easy stuff like turning dots into hyphens, then YY into YYYY. Macro operations can be of great help. It's difficult to be more specific, unfortunately. Maybe post some examples.

If the day or month may only be one digit then you'll have filenames with things like 12118. How would it know if that is 12-1-18 or 1-21-18?

I think its best for ones that are 12118 I should do manually.

Is there anyway I can make it change to 8 digits if its with periods or middle brackets if its 4, 5, 6 or 7 digits?

Such as: 9-6-18 or 2018-9-6 to YYYY-MM-DD

(.*[^0-9])([0-9]?[0-9])[-.]?([0-9][0-9])[-.]?([0-9][0-9][0-9][0-9])(.[^.]+)

\1\4.\2.\3\5

this should work
([0-9]{1,2})[-.]([0-9]{1,2})[-.]([0-9]{2,4})|([0-9]{2,4})[-.]([0-9]{1,2})[-.]([0-9]{1,2})|((?:19|20)[0-9]{2})([0-9]{2})([0-9]{2})|([0-9]{2})([0-9]{2})((?:19|20)[0-9]{2})
But I don't know how to reference more than 9 references in dopus, \11 and ${11} do not work.

So you will need to chose if you want YYYYMMDD or DDMMYYYY i guess.

regxp: ([0-1]?\d)[-.]([0-3]?\d)[-.]((?:19|20)?[0-9]{1,2})|((?:19|20)?[0-9]{1,2})[-.]([0-3]?\d)[-.]([0-1]?\d)|((?:19|20)?[0-9]{2})([0-3]?\d)([0-1]?\d)
replace: \1\6\9.\2\5\8.\3\4\7
Matches
DD-MM-YYYY
D-M-YY
YY-M-D
YYYY-M-D
YYMMDD
YYYYMMDD

What will confuse it is DD-MM-YY or YY-MM-DD or MMDDYYYY.

1 Like

I appreciate the help, however, this isn't working for me. Its just changing the middle hyphens to a period.

Also, I typically have files with the month first, then the day, followed by the year. Instead of the day first.

Any ideas why its not working? Its not adding the missing "0" digits and its not in the YYYY-MM-DD format

To pad the values you would need to use a rename script.

I would love some help if you don't mind. I honestly don't know where to begin.

This works ok. But you should set up some sample files for testing on.
There are some details here on how to use it Rename Scripts

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

function OnGetNewName(getNewNameData)
{
	var year;
	var month;
	var day;
	var matched = false;
	var item = getNewNameData.item;
	//DD-MM-YYYY D-M-YY
	var reg = new RegExp('([0-1]?\\d)[-.]([0-3]?\\d)[-.]((?:19|20)?[0-9]{1,2})|((?:19|20)?[0-9]{1,2})[-.]([0-3]?\\d)[-.]([0-1]?\\d)');
	if(reg.test(item.name))
	{
    	DOpus.OutputString(item.name + " matched 1 DD-MM-YYYY or YYYY-MM-DD");
		day = item.name.replace(reg, "$1$6");
   		month = item.name.replace(reg, "$2$5");
   		year = item.name.replace(reg, "$3$4");
		matched = true;
    }

	if(!matched)
	{
		//DDMMYYYY
		var reg = new RegExp('([0-1]?\\d)([0-3]?\\d)((?:19|20)[0-9]{2})');
		var regexMatch = reg.exec(item.name);
	    if (regexMatch != null) {
			DOpus.OutputString(item.name + " matched 2 DDMMYYYY");
			day = regexMatch[1];
	   		month = regexMatch[2];
	   		year = regexMatch[3];
			matched = true;
	    }
	}

	if(!matched)
	{
		//YYYYMMDD
		var reg = new RegExp('((?:19|20)?[0-9]{2})([0-3]?\\d)([0-1]?\\d)');
		var regexMatch = reg.exec(item.name);
	    if (regexMatch != null) {
			DOpus.OutputString(item.name + " matched 3 YYYYMMDD");
			day = regexMatch[3];
	   		month = regexMatch[2];
	   		year = regexMatch[1];
			matched = true;
	    }
	}
	
	if (matched)
	{
		getNewNameData = lpad(day, "00") + "-" + lpad(month, "00") + "-" + lpad(year, "0020");
		return lpad(day, "00") + "-" + lpad(month, "00") + "-" + lpad(year, "0020");
	}

	return true;
}

Thank you so much for all the help, wowbagger. There's no way I could have done this. I really appreciate it.

I do have a couple questions if you don't mind.

  • I'm looking for it to output with the year first such as YYYY-MM-DD.
  • Is there a way to make it work if there is other text within the filename? Some files output incorrectly or remove all the text from the original filename. If the file has an extension it will mess up. Your example only works on folders.

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

function ProduceNewName(oldname, matched, day, month, year) {
  var newDate  = lpad(year, "0020") + "-" + lpad(month, "00") + "-" + lpad(day, "00");
  DOpus.OutputString("'" + oldname +"' - '" + matched +"' - '" + newDate +"' day:'" + day +"' month:'" + month + "' year:'"+year+"'");
  return oldname.replace(matched, newDate);
}

function OnGetNewName(getNewNameData)
{
	var item = getNewNameData.item;
	//DD-MM-YYYY D-M-YY
	var reg = new RegExp('([0-1]?\\d)[-.]([0-3]?\\d)[-.]((?:19|20)?[0-9]{1,2})|((?:19|20)?[0-9]{1,2})[-.]([0-3]?\\d)[-.]([0-1]?\\d)');
	var regexMatch = reg.exec(item.name);
  	if (regexMatch != null) {
		DOpus.OutputString(item.name + " matched 1 DD-MM-YYYY or YYYY-MM-DD");
		getNewNameData = ProduceNewName(item.name, regexMatch[0], 
			regexMatch[1] + regexMatch[6],
			regexMatch[2] + regexMatch[5],
			regexMatch[3] + regexMatch[4]);
		return getNewNameData;
    }

	//DDMMYYYY
	var reg = new RegExp('([0-1]?\\d)([0-3]?\\d)((?:19|20)[0-9]{2})');
	var regexMatch = reg.exec(item.name);
    if (regexMatch != null) {
		DOpus.OutputString(item.name + " matched 2 DDMMYYYY");
	    getNewNameData = ProduceNewName(item.name, regexMatch[0], regexMatch[1], regexMatch[2], regexMatch[3])
		return getNewNameData;
    }

	//YYYYMMDD
	var reg = new RegExp('((?:19|20)?[0-9]{2})([0-3]?\\d)([0-1]?\\d)');
	var regexMatch = reg.exec(item.name);
    if (regexMatch != null) {
		DOpus.OutputString(item.name + " matched 3 YYYYMMDD");
	    getNewNameData = ProduceNewName(item.name, regexMatch[0], regexMatch[3], regexMatch[2], regexMatch[1])
		return getNewNameData;
    }

	//Failed, true means no change.
	return true;
}

image

1 Like

You are the best!!! thank you so much

I found one issue and was wondering if you could help one last time.

If you have a day that is between 20-31, it changes it to 023.

Example: 2018-07-23 would change to 2018-07-023, but it should stay the same since it is already in the correct format (YYYY-MM-DD)

Had the day month match reversed in one place.
I didnt spend time to verify if this caused other issues.

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

function ProduceNewName(oldname, matched, day, month, year) {
  var newDate  = lpad(year, "0020") + "-" + lpad(month, "00") + "-" + lpad(day, "00");
  DOpus.OutputString("'" + oldname +"' - '" + matched +"' - '" + newDate +"' day:'" + day +"' month:'" + month + "' year:'"+year+"'");
  return oldname.replace(matched, newDate);
}

function OnGetNewName(getNewNameData)
{
	var item = getNewNameData.item;
	//DD-MM-YYYY D-M-YY
	var reg = new RegExp('([0-1]?\\d)[-.]([0-3]?\\d)[-.]((?:19|20)?[0-9]{1,2})|((?:19|20)?[0-9]{1,2})[-.]([0-1]?\\d)[-.]([0-3]?\\d)');
	var regexMatch = reg.exec(item.name);
  	if (regexMatch != null) {
		DOpus.OutputString(item.name + " matched 1 DD-MM-YYYY or YYYY-MM-DD");
		getNewNameData = ProduceNewName(item.name, regexMatch[0], 
			regexMatch[1] + regexMatch[6],
			regexMatch[2] + regexMatch[5],
			regexMatch[3] + regexMatch[4]);
		return getNewNameData;
    }

	//DDMMYYYY
	var reg = new RegExp('([0-1]?\\d)([0-3]?\\d)((?:19|20)[0-9]{2})');
	var regexMatch = reg.exec(item.name);
    if (regexMatch != null) {
		DOpus.OutputString(item.name + " matched 2 DDMMYYYY");
	    getNewNameData = ProduceNewName(item.name, regexMatch[0], regexMatch[1], regexMatch[2], regexMatch[3])
		return getNewNameData;
    }

	//YYYYMMDD
	var reg = new RegExp('((?:19|20)?[0-9]{2})([0-3]?\\d)([0-1]?\\d)');
	var regexMatch = reg.exec(item.name);
    if (regexMatch != null) {
		DOpus.OutputString(item.name + " matched 3 YYYYMMDD");
	    getNewNameData = ProduceNewName(item.name, regexMatch[0], regexMatch[3], regexMatch[2], regexMatch[1])
		return getNewNameData;
    }

	//Failed, true means no change.
	return true;
}

image

1 Like

Everything seems to work fine after a quick test.

The only thing that doesn't work, which I guess wasn't a feature requested, was if a filename had the month in text."jan 10, 2017.pdf" etc.

Apologies for opening an old topic.

i also having similar interest. need help to modified the script to change to month-day-year and it wont work.

In function ProduceNewName change line that sets newDate to your desired format.

  • old: var newDate = lpad(year, "0020") + "-" + lpad(month, "00") + "-" + lpad(day, "00");
  • new: var newDate = lpad(month, "00") + "-" + lpad(day, "00") + "-" + lpad(year, "0020");

Thanks, is there anyway to just output YY instead of the YYYY. So mm-dd-yy

you can use substring to remove the first two chars from the year.
In function ProduceNewName change line that sets newDate to your desired format.

  • old: var newDate = lpad(year, "0020") + "-" + lpad(month, "00") + "-" + lpad(day, "00");
  • new: var newDate = lpad(month, "00") + "-" + lpad(day, "00") + "-" + lpad(year, "0020").substring(2,4);
1 Like

Hello all,

awesome thread!

I got a file/folder structure on a network drive with half a million files and folders. A considerable part of the files and folders are (consistently) named as follows:

YYYYMMDD[any character string].[any file extension]

How do I best proceed to rename all (and only those) files and folders corresponding to this naming pattern, so that the result looks like this:

YYYY-MM-DD[any character string].[any file extension]

Probably this is fairly straightforward to do with a RegEx, except that I'm not very fluent in RegEx :man_shrugging:

Also, I am of course grateful for any hints if this renaming might have any negative consequences, apart from a slight lengthening of the file/folder paths (and possibly breaking links and shortcuts).

Thanks very much!