The program was deliberately designed to be quick to set up and easy to use. The quick-and-easy tradeoff is that it can generate only timetables for single trains, or for westbound/eastbound pairs of trains; and it’s not good at generating timetables for trains that split enroute. It can do the latter, but it takes more work on the part of the user.
A few examples of the generated timetables are shown in Appendix A.
If you’d like something fancier (written in Python, not C++), check this out.
Tip o’ the hat to Dixieland Software for knowing all the trains’ schedules. 😁
Also, juckins.net has much prettier PDF timetables of the sort that Amtrak used to publish.
You’ll need a C++ implementation that conforms at least to C++11. Pretty much any moderately recent GCC will work just fine for POSIX operating systems, and it’s free. Microsoft Visual C++ from around 2015 or so should work OK for Windows. (IIRC, there’s a free version of the Microsoft compiler and standard library that’s good enough if all you want to do is write console apps, which is what this program is; but this writer can’t remember what Microsoft calls it.)
Just put station-codes.inc in some directory where #include with quotes can find it (probably the same directory where you put make-timetable.cpp), then compile the program from a command line. You won’t need any fancy makefile, and a GUI build tool will just get in the way.
http://dixielandsoftware.net/cgi-bin/getschedule.pl?seltrain=the-train-number
Or if you’d prefer, you can use the following little HTML page to get the data.
<html> <head> <title>Amtrak Train Schedules</title> <!-- by Bill Seymour, 2022-12-30 This file is in the public domain. --> </head> <body> <center> <h2>Get an Amtrak Train Schedule</h2> <form name="form" method=GET action="http://dixielandsoftware.net/cgi-bin/getschedule.pl"> Train number: <input type=text name="seltrain" size=4 maxlength=4> <p><input type=submit value="Submit"> </form> </center> </body> </html>
For example, the URL:
http://dixielandsoftware.net/cgi-bin/getschedule.pl?seltrain=302will load your browser with something that looks like:
* Schedule For Train 302. Formatted Data * Lincoln Service (PDF Schedule) * +---------------- Station Code * | +----------- Schedule Arrival Day * | | +-------- Schedule Arrival Time * | | | +----- Schedule Departure Day * | | | | +-- Schedule Departure Time * | | | | | +------------- Actual Arrival Time * | | | | | | +------- Actual Departure Time * | | | | | | | +- Comments * V V V V V V V V STL * * 1 640A CT ALN * * 1 725A CT CRV * * 1 752A CT SPI * * 1 832A CT LCN * * 1 856A CT BNL * * 1 930A CT PON * * 1 959A CT DWT * * 1 1017A CT JOL * * 1 1104A CT SMT * * 1 1129A CT CHI 1 1205P * * CT
Then in your browser, Edit->Select All and Edit->Copy to a text file
on your hard drive. The files can be in any directory and have any filenames you want; but
it’ll be easier for you later if you put them in what will be the current working directory when you run
the timetable generator, and name the files
If you wind up with blank lines at the beginning and the end, don’t worry; the generator program will happily ignore leading and trailing blank lines in its input files.
Let’s say that you’ve downloaded the raw data for trains 29, 30 and 2150 into files named 29sked.txt, 30sked.txt and 2150sked.txt, and those files are in what will be the current working directory when you run the generator program. In that case, you can generate the first two examples shown in Appendix A with the commands
make-timetable 29 30and
make-timetable 2150The generated files will be in the current working directory and have the names, 29sked.html and 2150sked.html.
But you can get fancier with the filenames if you want to.
If a command-line argument is a decimal number of one to four digits, the program assumes that it’s a train number; but anything else is assumed to be the full or relative path for the input file. For example, if you have a file named 2150.sked in the /train/schedules directory on a POSIX system, then the command
make-timetable /train/schedules/2150.skedwill do the same thing as the second command above. (In Windows, the directory separator is CP/M’s backslash, “\”.)
The path to the output file defaults to [train-number]sked.html in the current working directory, where [train-number] is taken from the input file specified by the first, or only, argument; but you can get around that, too. Just use the -o option (“o” for “output”) followed by the full or relative path to the file that you want the generator to create. For example, the command
make-timetable 29 30 -o CapitolLimited.htmlwill also create the first example in Appendix A, but in a file named CapitolLimited.html in the current working directory.
Or instead of using the -o option followed by a file path, you can use just -s to send the generated timetable to the standard output. This might be useful if you want to pipe the output to some other program that massages the HTML further.
29 | 🠠 Train Number 🠢 | 30 | ||||
---|---|---|---|---|---|---|
Read Down | Station | Read Up | ||||
Day | Time | Code | Name | Time Zone | Time | Day |
1 | 16:05 | WAS | Washington - Union Station, DC | ET | 13:05 | 2 |
16:29 | RKV | Rockville, MD | 12:16 | |||
17:16 | HFY | Harpers Ferry, WV | 11:31 | |||
17:45 | MRB | Martinsburg, WV | 11:01 | |||
19:17 19:24 | CUM | Cumberland, MD | 09:32 09:20 | |||
21:47 | COV | Connellsville, PA | 06:59 | |||
23:48 23:59 | PGH | Pittsburgh, PA | 05:20 05:05 | |||
2 | 01:39 | ALC | Alliance, OH | 03:05 | ||
02:53 02:59 | CLE | Cleveland, OH | 01:54 01:45 | |||
03:29 | ELY | Elyria, OH | 01:15 | |||
04:02 | SKY | Sandusky, OH | 00:40 | |||
05:08 05:22 | TOL | Toledo, OH | 23:49 23:39 | 1 | ||
06:36 | WTI | Waterloo, IN | 22:23 | |||
07:29 | EKH | Elkhart, IN | 21:29 | |||
07:51 | SOB | South Bend, IN | 21:09 | |||
08:45 | CHI | Chicago - Union Station, IL | CT | 18:40 |
Note that, for daily trains, the Day column contains just a day count.
2150 | 🠠 Train Number | |||
---|---|---|---|---|
Read Down | Station | |||
Day | Time | Code | Name | Time Zone |
MoTuWeThFr | 08:02 | NYP | New York - Penn Station, NY | ET |
08:47 | STM | Stamford, CT | ||
10:57 | PVD | Providence, RI | ||
11:24 | RTE | Westwood - Route 128, MA | ||
11:33 | BBY | Boston - Back Bay, MA | ||
11:39 | BOS | Boston - South Station, MA |
For a train that runs less often than daily, the Day column will contain the days that the train runs.
421 | 🠠 Train Number 🠢 | 422 | ||||
---|---|---|---|---|---|---|
Read Down | Station | Read Up | ||||
Day | Time | Code | Name | Time Zone | Time | Day |
SuTuFr | 13:45 | CHI | Chicago - Union Station, IL | CT | 13:44 | WeSaMo |
14:40 | JOL | Joliet, IL | 12:48 | |||
15:26 | PON | Pontiac, IL | 11:34 | |||
16:01 | BNL | Bloomington-Normal, IL | 11:02 | |||
16:30 | LCN | Lincoln, IL | 10:20 | |||
17:06 | SPI | Springfield, IL | 09:51 | |||
17:38 | CRV | Carlinville, IL | 09:09 | |||
18:09 | ALN | Alton, IL | 08:43 | |||
19:13 19:55 | STL | St. Louis, MO | 07:55 07:24 | |||
22:02 | ACD | Arcadia, MO | 04:19 | |||
23:42 | PBF | Poplar Bluff, MO | 02:44 | |||
MoWeSa | 00:37 | WNR | Walnut Ridge, AR | 01:41 | ||
03:10 | LRK | Little Rock, AR | 23:39 23:31 | TuFrSu | ||
03:55 | MVN | Malvern, AR | 22:26 | |||
04:20 | ARK | Arkadelphia, AR | 22:02 | |||
05:09 | HOP | Hope, AR | 21:18 | |||
05:58 | TXA | Texarkana, AR | 20:43 | |||
07:50 | MHL | Marshall, TX | 19:31 | |||
08:28 | LVW | Longview, TX | 18:15 | |||
09:25 | MIN | Mineola, TX | 17:15 | |||
11:30 11:50 | DAL | Dallas, TX | 15:40 15:20 | |||
13:25 14:10 | FTW | Fort Worth, TX | 14:20 13:58 | |||
14:52 | CBR | Cleburne, TX | 13:00 | |||
16:00 | MCG | McGregor, TX | 11:51 | |||
16:43 | TPL | Temple, TX | 11:25 | |||
17:36 | TAY | Taylor, TX | 10:22 | |||
18:30 | AUS | Austin, TX | 09:31 | |||
19:12 | SMC | San Marcos, TX | 08:32 | |||
MoWeSa TuThSu | 21:55 02:45 | SAS | San Antonio, TX | 07:00 04:50 | ||
TuThSu | 05:49 | DRT | Del Rio, TX | 01:02 | ||
08:24 | SND | Sanderson, TX | 22:36 | MoThSa | ||
10:38 | ALP | Alpine, TX | 20:45 | |||
13:22 13:47 | ELP | El Paso, TX | MT | 15:35 15:10 | ||
15:18 | DEM | Deming, NM | 13:10 | |||
16:13 | LDB | Lordsburg, NM | 12:15 | |||
18:18 | BEN | Benson, AZ | MST | 10:15 | ||
19:45 20:35 | TUS | Tucson, AZ | 09:15 08:28 | |||
21:52 22:02 | MRC | Maricopa, AZ | 06:40 06:30 | |||
WeFrMo | 00:49 | YUM | Yuma, AZ | 03:47 | ||
02:02 | PSN | Palm Springs - North, CA | PT | 00:36 | ||
03:54 | ONA | Ontario, CA | 22:54 | SuWeFr | ||
04:04 | POS | Pomona, CA | 22:41 | |||
05:35 | LAX | Los Angeles - Union Station, CA | 22:00 |
Creating the data to generate this one took the extra work described in Appendix B.
I first downloaded the data for train 1, the westbound Sunset Limited, and train 21, the westbound Texas Eagle. I then copied my 21sked.txt to 421sked.txt, and then appended to that the data from my 1sked.txt, but just from San Antonio to Los Angeles. That gave me (note the two data lines for San Antonio (SAS)):
* Schedule For Train 21. Formatted Data * Texas Eagle (PDF Schedule) * +---------------- Station Code * | +----------- Schedule Arrival Day * | | +-------- Schedule Arrival Time * | | | +----- Schedule Departure Day * | | | | +-- Schedule Departure Time * | | | | | +------------- Actual Arrival Time * | | | | | | +------- Actual Departure Time * | | | | | | | +- Comments * V V V V V V V V CHI * * 1 145P CT JOL * * 1 240P CT PON * * 1 326P CT BNL * * 1 401P CT LCN * * 1 430P CT SPI * * 1 506P CT CRV * * 1 538P CT ALN * * 1 609P CT STL 1 713P 1 755P CT ACD * * 1 1002P CT PBF * * 1 1142P CT WNR * * 2 1237A CT LRK * * 2 310A CT MVN * * 2 355A CT ARK * * 2 420A CT HOP * * 2 509A CT TXA * * 2 558A CT MHL * * 2 750A CT LVW * * 2 828A CT MIN * * 2 925A CT DAL 2 1130A 2 1150A CT FTW 2 125P 2 210P CT CBR * * 2 252P CT MCG * * 2 400P CT TPL * * 2 443P CT TAY * * 2 536P CT AUS * * 2 630P CT SMC * * 2 712P CT SAS 2 955P * * CT SAS 2 1205A 2 245A CT DRT * * 2 549A CT SND * * 2 824A CT ALP * * 2 1038A CT ELP 2 122P 2 147P MT DEM * * 2 318P MT LDB * * 2 413P MT BEN * * 2 618P MST TUS 2 745P 2 835P MST MRC 2 952P 2 1002P MST YUM * * 3 1249A MST PSN * * 3 202A PT ONA * * 3 354A PT POS * * 3 404A PT LAX 3 535A * * PTI then changed the train number to 421 and the train name to “Texas Eagle cars that run through to Los Angeles”, combined the two entries for SAS, adjusted the arrival and departure days accordingly, and appended the days of operation to the first data line. (The through cars to Los Angeles depart Chicago on Sunday, Tuesday and Friday.) That gave me (note the single entry for SAS with train 21’s arrival time and train 1’s departure time):
* Schedule For Train 421. Formatted Data * Texas Eagle cars that run through to Los Angeles (PDF Schedule) * +---------------- Station Code * | +----------- Schedule Arrival Day * | | +-------- Schedule Arrival Time * | | | +----- Schedule Departure Day * | | | | +-- Schedule Departure Time * | | | | | +------------- Actual Arrival Time * | | | | | | +------- Actual Departure Time * | | | | | | | +- Comments * V V V V V V V V CHI * * 1 145P CT SuTuFr JOL * * 1 240P CT PON * * 1 326P CT BNL * * 1 401P CT LCN * * 1 430P CT SPI * * 1 506P CT CRV * * 1 538P CT ALN * * 1 609P CT STL 1 713P 1 755P CT ACD * * 1 1002P CT PBF * * 1 1142P CT WNR * * 2 1237A CT LRK * * 2 310A CT MVN * * 2 355A CT ARK * * 2 420A CT HOP * * 2 509A CT TXA * * 2 558A CT MHL * * 2 750A CT LVW * * 2 828A CT MIN * * 2 925A CT DAL 2 1130A 2 1150A CT FTW 2 125P 2 210P CT CBR * * 2 252P CT MCG * * 2 400P CT TPL * * 2 443P CT TAY * * 2 536P CT AUS * * 2 630P CT SMC * * 2 712P CT SAS 2 955P 3 245A CT DRT * * 3 549A CT SND * * 3 824A CT ALP * * 3 1038A CT ELP 3 122P 3 147P MT DEM * * 3 318P MT LDB * * 3 413P MT BEN * * 3 618P MST TUS 3 745P 3 835P MST MRC 3 952P 3 1002P MST YUM * * 4 1249A MST PSN * * 4 202A PT ONA * * 4 354A PT POS * * 4 404A PT LAX 4 535A * * PT
I then did the same thing with 2sked.txt and 22sked.txt to make 422sked.txt, except that the data for train 2 from Los Angeles to San Antonio was put at the beginning, not the end, and the days of operation were already there on the Los Angeles line.
I now had 421sked.txt and 422sked.txt which I used to generate the timetable just as I would for any other pair of trains.
Because Dixieland Software provides raw data only between Spokane and Portland for the Portland section of the Empire Builder, and only between Boston and Rensselaer for the Boston section of the Lake Shore Limited, I used basically the same method to generate timetables for trains 27/28 and 449/448.
As another example, I also wanted to create a timetable for train 21 westbound just to St. Louis and train 302 eastbound to Chicago. Unfortunately, the timetable generator is picky about pairs of trains stopping at exactly the same stations. To make that work, I copied 21sked.txt to 321sked.txt (321 and 322 were older train numbers for set-out coaches that ran just between Chicago and St. Louis), made the train number and train name changes, deleted all the data after St. Louis (including the St. Louis departure day and time), and added stops at Summit and Dwight, but with neither arrival nor departure times (because the Texas Eagle doesn’t stop at those two stations). That gave me:
* Schedule For Train 321. Formatted Data * Texas Eagle (Chicago-St. Louis only) (PDF Schedule) * +---------------- Station Code * | +----------- Schedule Arrival Day * | | +-------- Schedule Arrival Time * | | | +----- Schedule Departure Day * | | | | +-- Schedule Departure Time * | | | | | +------------- Actual Arrival Time * | | | | | | +------- Actual Departure Time * | | | | | | | +- Comments * V V V V V V V V CHI * * 1 145P CT SMT * * 1 * CT JOL * * 1 240P CT DWT * * 1 * CT PON * * 1 326P CT BNL * * 1 401P CT LCN * * 1 430P CT SPI * * 1 506P CT CRV * * 1 538P CT ALN * * 1 609P CT STL 1 713P * * CT
I then ran the command,
321 | 🠠 Train Number 🠢 | 302 | ||||
---|---|---|---|---|---|---|
Read Down | Station | Read Up | ||||
Day | Time | Code | Name | Time Zone | Time | Day |
1 | 13:45 | CHI | Chicago - Union Station, IL | CT | 12:05 | 1 |
SMT | Summit, IL | 11:29 | ||||
14:40 | JOL | Joliet, IL | 11:04 | |||
DWT | Dwight, IL | 10:17 | ||||
15:26 | PON | Pontiac, IL | 09:59 | |||
16:01 | BNL | Bloomington-Normal, IL | 09:30 | |||
16:30 | LCN | Lincoln, IL | 08:56 | |||
17:06 | SPI | Springfield, IL | 08:32 | |||
17:38 | CRV | Carlinville, IL | 07:52 | |||
18:09 | ALN | Alton, IL | 07:25 | |||
19:13 | STL | St. Louis, MO | 06:40 |
(The timetable generator has no problem when the left and right trains have different names, and it’s happy to just leave a time cell empty when there’s neither an arrival nor a departure time, but fixing the “gotta be all the same stops” issue is coming Real Soon Now.)
First, get the current list of Amtrak stations from
https://juckins.net/amtrak_status/archive/html/stations.php;
then in your browser, highlight just the code/name pairs and copy them to a plain text file on your hard drive. (Or if you
think it’s easier, you could
Then compile make-sta-codes.cpp and run it, redirecting the station list you got from juckins.net to the standard input, and redirecting the standard output to station-codes.inc. When that’s done, recompile make-timetable.cpp.
All this program does is to read lines that have the form, “
If you care, the actual code in make-timetable.cpp is just
struct sta_codes { const char* code; const char* name; }; static const sta_codes stations[] = { #include "station-codes.inc" }; |
If you’re a non-geek who’s using a Mac, you might already have what you need. Just put the make-timetable.cpp and station-codes.inc files in whatever directory to want to use for these source files, open a bash shell window, cd to the directory you chose, and try
g++ make-timetable.cppIf that works, you will have created a file named a.out. Just mv a.out to a file named make-timetable (with no extension) in some directory that’s in your PATH environment variable, and you’re done.
If that doesn’t work, you’ll need to download and install the latest and greatest GCC. If you don’t know what I’m talking about, that’s OK; somebody at your local Apple store, or any other computer repair shop that works on Macs, should be able to install GCC for you.
If you’re running Windows, you’ll need to download and install Microsoft Visual C++. Again, there will probably be somebody at your local computer repair shop who knows how to do that. All you need is the version that lacks all the libraries that you need to create Windows programs since you’ll only be creating a console app. IIRC, that version is free (but YMMV).
The Windows command to compile the program is
cl /EHsc /W4 make-timetable.cppIf the compiler has been installed correctly, that will run without any errors or warnings and create two files, make-timetable.exe and make-timetable.obj. Move the .exe file to some directory in your PATH environment variable. You can just delete the .obj file.