4

With this code to get ymd:

var ymd = '20190716';
var year = ymd.substring(0, 4);
var month = ymd.substring(4, 2);
var day = ymd.substring(6, 2);

console.log(year);
console.log(month);
console.log(day);

I think its the right way to get substring from index to length. So ...

Want:

2019
07
16

But got:

2019
19
1907

Why?

adiga
  • 34,372
  • 9
  • 61
  • 83
02040402
  • 729
  • 3
  • 6
  • 21

3 Answers3

5

Check the docs:

The substring() method returns the part of the string between the start and end indexes, or to the end of the string.

and

If indexStart is greater than indexEnd, then the effect of substring() is as if the two arguments were swapped.

So when you pass 4, 2 or 6, 2, you're saying that you want the end index to come before the start index, so the arguments get switched, and you get index 2 to 4, and index 2 to 6.

Perhaps you wanted substr, which does what you're expecting:

The arguments of substring() represent the starting and ending indexes, while the arguments of substr() represent the starting index and the number of characters to include in the returned string.

var ymd = '20190716';
var year = ymd.substr(0, 4);
var month = ymd.substr(4, 2);
var day = ymd.substr(6, 2);
console.log(year);
console.log(month);
console.log(day);

But it's (kinda) deprecated. I'd prefer substring or slice, and pass indicies.

The substring() method swaps its two arguments if indexStart is greater than indexEnd, meaning that a string is still returned. The slice() method returns an empty string if this is the case.

slice's behavior is a bit more intuitive IMO.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Interesting: [Why String.prototype.substr() seems to be deprecated?](https://stackoverflow.com/q/52640271/1220550) – Peter B Jul 16 '19 at 08:22
3

The second argument of substring() is not the length of the substring you would like to get but the end index.

So substring(4,2) starts at index 4 and ends at 2. Giving you "19"

Bas Slagter
  • 9,831
  • 7
  • 47
  • 78
  • 1
    `.substr()`, on the other hand, accepts the start index and the length. – AKX Jul 16 '19 at 08:16
  • 1
    @AKX [`substr`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) is deprecated. [`slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) is a better option – adiga Jul 16 '19 at 08:18
  • Interesting: [Why String.prototype.substr() seems to be deprecated?](https://stackoverflow.com/q/52640271/1220550) – Peter B Jul 16 '19 at 08:22
  • @adiga although .slice() also has the end index as second argument – Bas Slagter Jul 16 '19 at 08:22
  • @BasSlagter yeah. You'd have to do `str.slice(index, index + length)`. I like it because I don't have to google to check every time if it's `substring` or `subString` or `substr`. It behaves exactly like `Array.prototype.slice` – adiga Jul 16 '19 at 08:35
1

You can also use JavaScript regex:

const date = "20190716";
const pattern = /(\d{4})(\d{2})(\d{2})/;
[result, year, month, day] = date.match(pattern);

console.log(year, month, day);

1st Capturing Group (\d{4})

  • \d{4} matches a digit (equal to [0-9])
  • {4} Quantifier — Matches exactly 4 times

2nd Capturing Group (\d{2})

  • \d{2} matches a digit (equal to [0-9])

  • {2} Quantifier — Matches exactly 2 times

3rd Capturing Group (\d{2})

  • \d{2} matches a digit (equal to [0-9])

  • {2} Quantifier — Matches exactly 2 times

Rohit.007
  • 3,414
  • 2
  • 21
  • 33