Skip to content
The AI Agent Factory

13.7 Text, dates and files

Approved by
Panaversity ·
11 min read

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 true

Why 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.

CaseExampleResult
Crossing a month end2026-10-20 plus 15 days2026-11-04
Crossing a year end2026-12-20 plus 30 days2027-01-19
A leap year2028-02-15 plus 15 days2028-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.

LanguageWhat it holds
TypeScriptDate 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.
Pythondate 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));
LanguageThe rule line
TypeScriptsetUTCDate 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.
Pythontimedelta(days=days) is a length of time, added to the date.

Both print:

2026-11-04 2027-01-19 2028-03-01

Try 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. A calendar strip crossing a month end: October 20 plus 15 days lands on November 4, and February 15, 2028 plus 15 days lands on March 1 because of the leap day.

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