loading...

Two string methods every JavaScript developer should know.

Audiophile on November 14, 2019

The Challenge: I was working on a project recently where I was required to build an endpoint that enabled the client to be able to query... [Read Full]
markdown guide
 

So far is fine to play a bit with strings. But I'd like to share from my experience, always try to manipulate the objects with their respective API. In this case you are facing a formatted string RFC-3339, and you want to extract its = date-fullyear "-" date-month "-" date-mday

I highly recommend to avoid regex. You should implement Date API, you can achieve easily with 2 lines of code and solid code scalable. As many other answered to you, try to play with Date, as example:

const date = new Date("2019-08-02T00:00:00.000Z")

const fullDate = ${date.getFullYear()}-${date.getMonth()}-${date.getDay()}

Note: toLocaleString is experimental and not stable yet.

You may normalize getMonth and getDay to add 0 to the left when needed.

 

"Note: toLocaleString is experimental and not stable yet."

For Date (and most other built-in objects)? No it isn't.

developer.mozilla.org/en-US/docs/W...

 

They would have still needed to use string.replace to remove the double quotes around the date string, but I prefer your approach of using the Date APIs to ensure you're always going to get the same result.

 

Not necessarily, you could do it with String.slice or JSON.parse instead.

 

Yes, this was my first thought as well. Using the Date built in functions.

 

Great post!.

Whenever I'm in a position where I can implement different solutions to the same problem involving strings, I try to follow this decision tree:

desicion tree

I always try to write solutions with as few lines as possible without compromising readability.

For your task, this also works:

> let date = '"2019-08-02T00:00:00.000Z"'
> date.substring(date.indexOf('"') + 1, date.indexOf("T"))
'2019-08-02'
 

If it's a fixed format you can just slice it out without having to spend CPU cycles searching.

const dt = '"2019-08-02T00:00:00.000Z"';
const date = dt.slice(1,11);
console.log(date);

The methods in the article are definitely handy to have in your toolkit though.

 

.slice(), .substr() and .substring() can all achieve this but I agree completely that it should be done with the fixed indexes since its quite apparent the data is all in the same format given his example and glad that my first thought was apparently the most efficient!

edit: turns out substr is non-standard and substring should be used instead

 

Wow this is brilliant, didn't know you could do that in just one line of code. Thanks for sharing Fidel, I appreciate it!

 

Since you know the exact input maybe less is more here?
let date = '"2019-08-02T00:00:00.000Z"';
date = date.substr(1, 10);

 

Substr should not be used. Instead use substring


String.prototype.substr(…) is not strictly deprecated (as in "removed from the Web standards"), it is considered a legacy function and should be avoided when possible. It is not part of the core JavaScript language and may be removed in the future. If at all possible, use the substring() method instead.

developer.mozilla.org/en-US/docs/W...

 

Interesting...
But how about this?

new Date("2019-08-02T00:00:00.000Z").toLocaleDateString("sq-AL",{ year: 'numeric', month: '2-digit', day: '2-digit' })

 

This method will only work if your javascript environment (browser or server in case of nodejs) is guaranteed to run in UTC. In case of other timezones or daylight saving time shift you can get an error of +-1 days as Date object parses this to local environment time.

 

Actually... No.
Date doesn't parse this to local environment time.
That string contains T00:00:00.000Z.It is timezone of date(UTC in current case) . So it will convert correct in every environment!

Exactly what I was saying, that this is only valid when that timezone containing string is generated in the same environment. I'm living in UTC+2 and parsing the string withe Zulu Z time in the end (set time to 23h to make the point):

new Date("2019-08-02T23:00:00.000Z").toLocaleDateString("sq-AL",{ year: 'numeric', month: '2-digit', day: '2-digit' });

returns 08/03/2019

That is way it is good practis to set all servers in utc

But you can not guarantee users with their computers to stay put in UTC too. Nobody told the string was parsed in server. If it was though then the split method just calls for SQL injection attack.

Also no sane person ever thought "put all your servers in the wrong timezone" was a good idea.

Instead of trying to work around bugs in your code by making every single recorded time in your server wrong, just learn the involved concepts and the available APIs.

 

This is the answer.

Also, it's strange, because I feel most people know about these string operations.

This is not the situation to use them though, it's mildly ridiculous this was the accepted answer...

To be more clear, the date function can parse more formats of dates then this fix, will the date always have a T? Also the format is decidedly js, which means it probably came from the date function already.

 

So you thought of using a RegEx, ended up discovering Split, then had to use a RegEx in your Replace anyway?

At that point you might as well go all-in:

const justDate = date.match(/"(.+)T/)[1]

(Typed on a phone, may not be perfect)

 

Hi Adam, so I guess the point for me was applying something that I understood. My knowledge of RegEx isn't the best, and I wanted to apply something in the code base I could explain if asked. Thanks for sharing!

 

That's fair, though I would argue the level of RegExiness involved here is something everyone should make a point of learning because it solves so many problems.

An even shorter alternative, since you know the input format won't change: const justDate = date.slice(1, 11).

 

Yea I was thinking the exact same thing. Probably didn't notice the /"/g was regex

 

Well written and easy to follow article.

I know your solution works, but manipulating an ISO datetime string directly makes me uncomfortable. I'd rather put it in a Date object or outside library and then format it in the desired way.

But I over-engineer things and your solution is simpler and has a lower cognitive load. Still learning this lesson.

Thanks for reminding me to keep it simple!

 

What happened here is that you got a datetime object formatted as json. So yes you could manually parse the json (it is pretty trivial after all), but there's a built-in solution to handle this: JSON.parse().

After you've done that you'll have to deal with the fact that JavaScript's datetime library is about as bad as possible. So instead of dealing with the catastrophe that the built-in API is, simply use moment.js. Which combined results in the rather pleasant moment(JSON.parse(inputStr)).format('YYYY-MM-DD')

(You should obviously do error handling along the way).

 
 
 

Haha turns out substr would get the T not the Z and substring would get the correct string with the same args

Both of you are wrong but okay... it would not get either.

date= '"2019-08-02T00:00:00.000Z"';
console.log(date.substr(1,11);

go ahead and run in your console. I'll wait.

 

As the old joke goes "I decided to use regex and now I have 2 problems"... regex is a very useful tool but doesn't need to be your only tool, and as usual with programming it's easy to overcomplicate things.

 

If I have to do this, I will use only regex replace instead of using both split and regex, where regex only already can achieve this :

var str = '"2019-08-02T00:00:00.000Z"';

var res = str.replace(/.*(\d{4}\-\d{2}\-\d{2}).*/, "$1");

This way also will not care about other string inside the string, it will just try to find 9999-99-99 and remove others.
It will accept any format with this pattern.

Eg. :
2019-08-02 00:00:00
Friday, 2019-08-02 00:00:00

 

Great explanations that even a noob like me can understand! Thank you! I'll be looking for more articles from you in the future.

 
 
 

Nicely done. You can certainly use regex in the future, but this time around you discovered the magic of split and replace for string manipulation. More tools in your code toolbox.

 

Why would you parse the date manually and then format it manually? Use Date.parse and toLocaleString stackoverflow.com/a/34015511/227299

-1

code of conduct - report abuse