13.7 Text, dates and files
- Approved by
- Panaversity ·
In everyday life. At 9 p.m. on Monday in Columbus, it is already Tuesday morning in Tokyo.
What you will learn. Text and dates carry rules you cannot see, and which of them to test on purpose.
Why it matters. Two values can look the same and not match, and a date can come out one day wrong.
What goes wrong when I read text from a file?
Reading a file gives you its whole content as one string, and the code splits it into lines and values. A missing file stops the program with an error that names the file's path, its address in the folders. 13.8 shows how to read it.
Windows ends each line with two invisible characters, a carriage return \r and a newline \n. Mac and Linux use only \n. A TypeScript script that splits on \n alone leaves a \r stuck to the last value on each line, so "open\r" is not "open". Like a space at the end of a spreadsheet cell, it looks the same, but a lookup does not match it. TypeScript's trim() and Python's strip() remove blank space from the ends.
Here is a Windows line, with \r at its end. split(",") cuts text at each comma and gives a list of the pieces. The code cuts the line twice: once as it is, and once after cleaning its ends. Predict both values.
const line = "INV-8301,V001,open\r";
const parts = line.split(","); // cut at each comma
const cleaned = line.trim().split(","); // clean the ends first, then cut
console.log(parts[2] === "open", cleaned[2] === "open");false trueWhy are dates hard?
Brightline writes every date as ISO text: year, month, day, such as 2026-11-06. ISO dates sort correctly as text, because each has the same length, zeros included, year first. So a script can compare due <= cutoff directly. Adding days is harder.
| Case | Example | Result |
|---|---|---|
| Crossing a month end | 2026-10-20 plus 15 days | 2026-11-04 |
| Crossing a year end | 2026-12-20 plus 30 days | 2027-01-19 |
| A leap year | 2028-02-15 plus 15 days | 2028-03-01, because February 2028 has 29 days |
Why can a test pass on one computer and fail on another?
Because of time zones. A date, such as October 20, is the same everywhere. A moment is one instant, and it can fall on different dates in different places: 9 p.m. on Monday in Columbus is Tuesday morning in Tokyo. Code that holds a moment can give a different day on two computers. Code that holds a date cannot.
| Language | What it holds |
|---|---|
| TypeScript | Date holds a moment, and some ways of making one use the computer's local time zone. TypeScript has no type for a plain calendar day. So Brightline's TypeScript does date math in UTC, the world reference time, and the result is the same on every computer. |
| Python | date is a calendar day with no time and no time zone, so it cannot slip this way. |
At work. The agent's first due-date function read the date with new Date("2026-10-07"), which is midnight UTC. Then it wrote the result in the computer's local time. Ana's tests passed on the team's build server, a shared computer set to UTC. On her computer in Columbus they failed by one day, because midnight UTC on October 7 is still 8 p.m. on October 6 there. The agent had mixed local time and UTC. The fix was to build every date in UTC.
Find the rule line. Adding days is counting forward on a wall calendar. You put a finger on the start day, count, and turn the page when the month runs out. You do not need every line of addDays, only the line that does the counting. The comments say what each line is for. Its answers should match the table.
function addDays(isoDate: string, days: number): string {
const start = `${isoDate}T00:00:00Z`; // the date, at midnight UTC
const date = new Date(start); // make a moment from it
const newDay = date.getUTCDate() + days; // the rule: count forward
date.setUTCDate(newDay); // past the month's end, turn the page
const fullText = date.toISOString(); // back to text
return fullText.slice(0, 10); // keep the date part
}
console.log(addDays("2026-10-20", 15), addDays("2026-12-20", 30), addDays("2028-02-15", 15));| Language | The rule line |
|---|---|
| TypeScript | setUTCDate sets the day in UTC, and moves on to the next month when the number is too big. In the first line, text between backticks can hold a value: ${isoDate} puts in what isoDate holds. |
| Python | timedelta(days=days) is a length of time, added to the date. |
Both print:
2026-11-04 2027-01-19 2028-03-01Try it
The file in 13-7 adds 15 days to a date, then checks a Windows line. Run it and investigate, as in 13.1.
Modify. Send: "Please change the date in the file to 2028-02-20, and clean the Windows line before it is split. Don't run it yet." Work out the new date on a calendar. February 2028 has 29 days. Then ask the agent to run it.
Make. Send: "Please make a new file in 13-7 called mine that adds 30 days to [a date of yours, across a year end]. Don't run it yet." Work out the answer yourself, and then ask the agent to run it.
What you should see. 2028-03-06, then true where it was false, because the invisible \r is gone.
The operating rule: keep dates as ISO text, do date math in UTC or with a calendar-day type, and test month ends, year ends, leap days and Windows line endings on purpose.

Figure 13.8. Date math crosses edges. The edges are where the bugs are, so they are where the tests go.
Next. 13.8 shows how to read what a program says when it breaks.
Check yourself
Question 1 / 6
0 answered
A TypeScript script splits a Windows file on \n alone. What happens to the last value on each line?
- Owner
- Panaversity