To convert a string to a date in TypeScript, pass an ISO 8601 string to new Date(), such as new Date("2026-10-08T14:30:00"). Then check the result, because a bad string gives an Invalid Date instead of an error, and a date-only string is read as UTC:
const d = new Date("2026-10-08T14:30:00");
if (Number.isNaN(d.getTime())) throw new Error("bad date");
Time zones change the answers here, so every run used TypeScript 7.0.2 with Node.js v22.22.2 with the time zone set to New York (Eastern Time).
You’ll see ISO strings with and without offsets, why a date-only string shows the previous day in the US, parsing MM/DD/YYYY safely, and how to spot an Invalid Date.
Convert an ISO string to a Date with new Date()
The ISO format is the only one every JavaScript engine must parse the same way. What you include decides the time zone:
const local = new Date("2026-10-08T14:30:00"); // no offset -> local time
const utc = new Date("2026-10-08T14:30:00Z"); // Z -> UTC
const offset = new Date("2026-10-08T14:30:00-07:00"); // Pacific daylight time
for (const [label, d] of [["local", local], ["utc", utc], ["offset", offset]] as const) {
console.log(label.padEnd(7), d.toString().slice(0, 33), "|", d.toISOString());
}
Output:
local Thu Oct 08 2026 14:30:00 GMT-0400 | 2026-10-08T18:30:00.000Z
utc Thu Oct 08 2026 10:30:00 GMT-0400 | 2026-10-08T14:30:00.000Z
offset Thu Oct 08 2026 17:30:00 GMT-0400 | 2026-10-08T21:30:00.000Z

No offset means local time; Z means UTC. The finer points of the format are in handling ISO date strings in TypeScript.
Why does my date string show the previous day?
A date-only string like "2026-10-08" is parsed as midnight UTC. In any US time zone that’s still the evening before, so the date looks one day early:
const due = new Date("2026-10-08"); // date-only ISO = UTC midnight
console.log(due.toISOString());
console.log(due.toDateString(), "<- shows Oct 7 in New York");
console.log("getDate():", due.getDate());
function parseLocalDate(s: string): Date {
const [y, m, d] = s.split("-").map(Number);
return new Date(y, m - 1, d); // months are 0-based
}
const fixed = parseLocalDate("2026-10-08");
console.log(fixed.toDateString(), "getDate():", fixed.getDate());
Output:
2026-10-08T00:00:00.000Z
Wed Oct 07 2026 <- shows Oct 7 in New York
getDate(): 7
Thu Oct 08 2026 getDate(): 8

Split the parts and call new Date(year, month - 1, day), which uses local time. Converting the other way, to UTC, is covered in converting dates to UTC in TypeScript.
Parse an MM/DD/YYYY string into a Date
US forms usually send MM/DD/YYYY. Engines aren’t required to support that format, and impossible dates like February 30 roll over silently. Parse it yourself and check the parts:
function parseUSDate(s: string): Date | null {
const m = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/.exec(s.trim());
if (!m) return null;
const [month, day, year] = [Number(m[1]), Number(m[2]), Number(m[3])];
const d = new Date(year, month - 1, day);
// reject 02/30/2026 and friends: Date silently rolls them into the next month
if (d.getFullYear() !== year || d.getMonth() !== month - 1 || d.getDate() !== day) return null;
return d;
}
for (const s of ["10/08/2026", "7/4/2026", "02/30/2026", "13/01/2026", "2026-10-08"]) {
const d = parseUSDate(s);
console.log(s.padEnd(11), "->", d ? d.toDateString() : "null");
}
console.log("built-in, 02/30/2026:", new Date("02/30/2026").toDateString());
Output:
10/08/2026 -> Thu Oct 08 2026
7/4/2026 -> Sat Jul 04 2026
02/30/2026 -> null
13/01/2026 -> null
2026-10-08 -> null
built-in, 02/30/2026: Mon Mar 02 2026

I use this round-trip check on every form date; it catches rollover. To show the result as text again, see formatting a date as MM/DD/YYYY in TypeScript.
Check whether a date string is valid
new Date() never throws. A string it can’t read gives a Date whose time is NaN, so test getTime():
function isValidDate(d: Date): boolean {
return !Number.isNaN(d.getTime());
}
for (const s of ["2026-10-08", "2026-13-45", "October 8, 2026", "next Friday", ""]) {
const d = new Date(s);
console.log(JSON.stringify(s).padEnd(18), isValidDate(d) ? d.toDateString() : "Invalid Date");
}
console.log("Date.parse:", Date.parse("2026-10-08T14:30:00Z"), typeof Date.parse("x"), Date.parse("x"));
Output:
"2026-10-08" Wed Oct 07 2026
"2026-13-45" Invalid Date
"October 8, 2026" Thu Oct 08 2026
"next Friday" Invalid Date
"" Invalid Date
Date.parse: 1791469800000 number NaN

Notice that 2026-10-08 shows Wed Oct 07 again: the same UTC trap as above. That’s why I never trust a date-only string straight from new Date().
Node accepts "October 8, 2026", but that format isn’t guaranteed everywhere. More validation patterns are in checking for invalid dates in TypeScript.
String to date methods compared
| Input | Use | Watch out for |
|---|---|---|
2026-10-08T14:30:00 | new Date(s) | Local time; add Z or an offset for UTC |
2026-10-08 | new Date(y, m - 1, d) | new Date(s) gives UTC midnight |
10/08/2026 | Regex + new Date(y, m - 1, d) | Rollover; engine differences |
| Anything from users | Number.isNaN(d.getTime()) | new Date() doesn’t throw |
| Need a timestamp | Date.parse(s) | Returns NaN, not an error |
Once you have a Date, date math such as calculating days between dates is straightforward.
For everyday date work in TypeScript, keep these handy:
- Convert a date to a string in TypeScript
- Compare dates in TypeScript
- Add days to a date in TypeScript
- Get the current date in TypeScript
Frequently asked questions
How do I convert a string to a Date in TypeScript?
Use new Date(isoString) and check Number.isNaN(d.getTime()) to catch invalid input.
Why is my date one day off?
A date-only ISO string is parsed as UTC midnight, which is the previous evening in US time zones. Build it with new Date(y, m - 1, d).
How do I parse MM/DD/YYYY in TypeScript?
Match it with a regex, then call new Date(year, month - 1, day) and confirm the parts didn’t roll over.
How do I check if a date string is valid?
Create the Date and test !Number.isNaN(d.getTime()); also check rollover for user-entered dates.
What’s the difference between new Date() and Date.parse()?
new Date() returns a Date object; Date.parse() returns milliseconds since 1970, or NaN.
Where is the Date string format documented?
See the date time string format on MDN.

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn