Your question can be broken down into two main parts:
1. Determine the state of the pregnancy progression.
The generally formula for this is.
(Estimated) Date of Conception + Average Gestation Period (in days) = Estimated Due Date.
... you will notices that the Due Date is an estimate because in real-life we don't actually know exactly when the birth will occur, unlike your game where you have the $birth variable with the exact date-time the baby is due.
The pregnancy progression can be also be expressed in two forms:
a. Period between the (Estimated) Date of Conception and Now. (eg. 10 weeks along)
b. Period between Now and the (Estimated) Due Date. (eg. 10 weeks to go.)
So you need to decide two things:
1. Do you want the "pregnancy progression" to be an estimate like it is in real life or not?
2. Do you want it to be calculated based on the (Estimated) Date of Conception or the (Estimated) Due Date?
How to calculate the number of weeks between two Date objects.
Detailed breakdown.
<<set $gameDate to new Date()>>\
<<set $birth to clone($gameDate)>>\
<<run $birth.setDate($birth.getDate() + 266 + random(-21, 14))>>\
current game date: <<= $gameDate>>
birth: <<= $birth>>
<<set _difference to $birth.getTime() - $gameDate.getTime()>>\
the milliseconds between the two dates: _difference
the milliseconds as seconds: <<= _difference / 1000>>
the milliseconds as minutes: <<= _difference / (1000 * 60)>>
the milliseconds as hours: <<= _difference / (1000 * 60 * 60)>>
the milliseconds as days: <<= _difference / (1000 * 60 * 60 * 24)>>
the milliseconds as weeks: <<= _difference / (1000 * 60 * 60 * 24 * 7)>>
Condensed version.
<<set $gameDate to new Date()>>\
<<set $birth to clone($gameDate)>>\
<<run $birth.setDate($birth.getDate() + 266 + random(-21, 14))>>\
current game date: <<= $gameDate>>
birth: <<= $birth>>
<<set _weeks to ($birth.getTime() - $gameDate.getTime()) / 604800000>>\
the weeks between the two dates: _weeks
... both of the above use the <Date>.getTime() function to convert a Date object into a integer representing the number of milliseconds that have pasted since a special predetermined point in time.
EDIT: The following is based on your decisions.
Because you have chosen to based things on the Estimated Date of Conception then you will need to track when that occurred, the following is a replacement for the existing code you are using to generate the $birth variable. It creates a $conception variable which is currently being set to be exactly the same as the current $gameDate, you may want to randomly change the $conception value by a couple of days depending on the logic of your "Impregnated" event(s) and if the player knows exactly when they occurred.
<<set $gameDate to new Date()>>\
<<set $conception to clone($gameDate)>>\
<<set $birth to clone($gameDate)>>\
<<run $birth.setDate($birth.getDate() + 266 + random(-21, 14))>>\
You can now use custom Javascript functions to determine if the NPC is pregnant, the estimated due date, and then number of weeks since conception. The following should be placed within your Story Javascript area, it relies on the existence of the new $conception variable.
/*
* Math.trunc Polyfill from MDN.
*/
if (!Math.trunc) {
Math.trunc = function(v) {
v = +v;
return (v - v % 1) ||
(! isFinite(v) || v === 0 ? v : v < 0 ? -0 : 0);
};
}
/*
* Returns true if NPC is pregnant, otherwise returns false.
*/
setup.isPregnant = function () {
return State.variables.hasOwnProperty("birth");
};
/*
* Returns the Estimated Due Date (based on date of conception)
* if the NPC is pregnant, otherwise returns null.
*/
setup.estimatedDueDate = function () {
var due = null;
if (setup.isPregnant()) {
var due = clone(State.variables["conception"]);
due.setDate(due.getDate() + 266);
}
return due;
};
/* Returns the number of weeks since the date of conception,
* otherwise returns -1.
*/
setup.weeksPregnant = function () {
if (! setup.isPregnant()) {
return -1; // Not Pregnant!
}
var conception = State.variables["conception"];
var now = State.variables["gameDate"];
var weeks = (now.getTime() - conception.getTime()) / 604800000;
/* The above weeks calculation could result in a decimal number
* (like 4.35) which doesn't make sense in R/L, for this reason
* the following removes the fractional digit part before returning
* the value.
*/
return Math.trunc(weeks);
};
... and you can used the new custom functions within a Passage like so.
<<silently>>
<<set $gameDate to new Date()>>\
<<set $conception to clone($gameDate)>>\
<<set $birth to clone($gameDate)>>\
<<run $birth.setDate($birth.getDate() + 266 + random(-21, 14))>>\
/% Move game forward 3 weeks, %/
<<run $gameDate.setDate($gameDate.getDate() + 21)>>
<<set _pregnant to setup.isPregnant()>>
<<set _due to setup.estimatedDueDate()>>
<<set _weeks to setup.weeksPregnant()>>
<</silently>>
\conception: <<= $conception>>
birth: <<= $birth>>
now: <<= $gameDate>>
The NPC is <<if _pregnant>>pregnant!<<else>>not pregnant!<</if>>
The NPC's estimated due date is: <<= _due>>
The NPC has been pregnant for <<= _weeks>> weeks.
note: you don't have to store the values returned by the custom function within variables, I just did that to make the above easier to understand.
2. Displaying status messages and the like based on the pregnancy progression.
How you do this greatly depends on exactly what you want to inform the Player about!
If you want to indicate that the NPC is having morning sickness then you could do something like the following.
<<if setup.weeksPregnant() is 6>>The NPC quickly rushed to the bathroom sink to throw up, you wonder they are pregnant.<</if>>
... or a range of outputs like the following.
<<set _weeks to setup.weeksPregnant()>>
<<if _weeks is 6>>The NPC has stated showing the signs of having morning sickness.
\<<elseif _weeks gt 6 and _weeks lte 10>>The NPC has stated showing the next signs being pregnant....
\<</if>>