Strings, Numbers, Dates, and Regex Awareness
The everyday string and number methods, locale-aware formatting, working with dates safely, and what problems regular expressions solve.
By the end of this lesson, you can
- Use common string methods to search, slice, and transform text without mutating the original string
- Format numbers and dates for a human reader using Intl, instead of hand-building strings
- Create a Date correctly and explain a common date-parsing pitfall
- Recognize what kind of problem a regular expression solves, without needing to write complex patterns yet
Why it matters
Displaying data to a person — a price, a date, a search result — is one of the most common things a program does, and it’s where correctness (does this handle every input?) meets presentation (does this read naturally to a human?). This lesson covers the everyday tools for both.
Strings are immutable
Every string method returns a new string; none of them modify the original, because strings — unlike arrays and objects — are primitives, and primitives can’t be mutated at all:
const raw = ' Hello, World! ';
console.log(raw.trim()); // "Hello, World!" — whitespace removed
console.log(raw.toLowerCase()); // " hello, world! "
console.log(raw.includes('World')); // true
console.log(raw.replace('World', 'JavaScript')); // " Hello, JavaScript! "
console.log(raw); // unchanged — still has its original whitespace and casing
| Method | Purpose | Example result |
|---|---|---|
| slice(start, end) | Extract a substring by position | "hello".slice(1, 3) → "el" |
| split(separator) | Break a string into an array | "a,b,c".split(",") → ["a","b","c"] |
| padStart(len, char) | Pad to a minimum length | "5".padStart(2, "0") → "05" |
| at(index) | Read a character, supporting negative indexes | "hello".at(-1) → "o" |
Formatting numbers and dates for people
Hand-building a formatted string ('$' + price.toFixed(2)) breaks down fast once locale, currency,
or grouping separators matter. Intl formats correctly for a given locale instead:
const price = 1234.5;
const usd = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
console.log(usd.format(price)); // "$1,234.50"
const percent = new Intl.NumberFormat('en-US', { style: 'percent' });
console.log(percent.format(0.42)); // "42%"Math provides the standard numeric operations beyond the basic arithmetic operators —
Math.round(), Math.max(), Math.min(), Math.abs(), Math.random() (which returns a decimal
from 0 up to, but not including, 1).
Dates
const now = new Date(); // the current moment
const specific = new Date(2026, 8, 3); // September 3, 2026 — NOTE: month is 0-indexed!
const fromString = new Date('2026-09-03'); // parses an ISO date string
console.log(specific.getFullYear(), specific.getMonth(), specific.getDate()); // 2026 8 3
Intl.DateTimeFormat formats a date for a human reader the same way Intl.NumberFormat handles
numbers:
const formatter = new Intl.DateTimeFormat('en-GB', { dateStyle: 'long' });
console.log(formatter.format(new Date(2026, 8, 3))); // "3 September 2026"
What regular expressions are for
A regular expression describes a pattern of text to search for or validate against — “does this
look like an email address,” “find every digit sequence” — more flexibly than includes() or
indexOf() can express. At this stage, it’s enough to recognize the shape and reach for one when a
plain string method can’t express the check:
const hasDigit = /\d/; // matches any single digit character
console.log(hasDigit.test('abc123')); // true
console.log(hasDigit.test('abcdef')); // false
const cleaned = 'a1b2c3'.replace(/\d/g, ''); // "abc" — g removes every match, not just the first
Check your understanding
Or reveal the answer without checking
Answer:"Hello"
toUpperCase() returns a new string — it doesn't mutate s, and the return value here is never stored or used. s is unchanged.
Or reveal the answer without checking
Answer:January 15, 2026
Date's month argument is zero-indexed, so 0 means January — new Date(2026, 0, 15) is January 15, 2026.
Practice: warm-up
Predict the output, then check: " JavaScript ".trim().length, "apple,banana,cherry".split(',').length,
"3".padStart(5, '0').
Stuck? Reveal one hint at a time.
Hint 1
trim() removes leading and trailing whitespace only — count the letters in "JavaScript".
Hint 2
split(",") turns a comma-separated string into an array; .length counts array elements, not characters.
Hint 3
padStart(5, "0") pads the string on the left with "0" until it reaches length 5.
Reveal the output
Try the problem yourself before reading this. There is often more than one reasonable approach — treat this as one worked example, not the only correct answer.
" JavaScript ".trim().length -> 10
"apple,banana,cherry".split(',').length -> 3
"3".padStart(5, '0') -> "00003"Practice: apply it
Write formatPrice(amount) that returns a US-currency-formatted string, and daysUntil(dateString)
that returns the number of whole days between today and a given ISO date string (a negative number
if the date is in the past).
Stuck? Reveal one hint at a time.
Hint 1
Intl.NumberFormat with { style: "currency", currency: "USD" } handles formatPrice directly.
Hint 2
For daysUntil, subtracting two Date objects gives a difference in milliseconds, not days.
Hint 3
Divide the millisecond difference by 1000 * 60 * 60 * 24 to get days, and round to a whole number.
Reveal a reference solution
Try the problem yourself before reading this. There is often more than one reasonable approach — treat this as one worked example, not the only correct answer.
function formatPrice(amount) {
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount);
}
function daysUntil(dateString) {
const msPerDay = 1000 * 60 * 60 * 24;
const target = new Date(dateString);
const today = new Date();
return Math.round((target - today) / msPerDay);
}Summary
- Strings are immutable primitives — every string method returns a new string, never modifying the original.
Intl.NumberFormatandIntl.DateTimeFormatproduce correctly localized output instead of hand-built strings, and should be the default over manual formatting.Date’s month parameter is zero-indexed (January is0); this is one of the most common sources of date bugs and simply has to be remembered.- A date-only string parses as UTC midnight, not local midnight — a frequent source of off-by-one- day bugs when displayed in local time.
- A regular expression matches a pattern of text, not one exact value — useful once a plain string method can’t express the check, without needing full pattern-writing fluency yet.