Add a general-purpose interpolater, and use it to interpolate GDP values for countries when we don't have exact data for specific years, e.g. Italy has 1936 and 1950, but not 1940, so now it's interpolated.
M src/main/java/DBObjects/CalculatedObjects/CurrencyFigure.java +3 -0
@@ 35,6 35,9 @@ public class CurrencyFigure {
     
     public CurrencyFigure convertTo(String resultCurrency) throws CurrencyConversionException {
         ExchangeRates rates = ExchangeRates.getExchangeOptions(new ExchangeRateKey(currency, year));
+        if (rates == null) {
+            throw new CurrencyConversionException(currency, resultCurrency, year, "Could not find applicable rates data");
+        }
         return rates.convertTo(resultCurrency, this, new ArrayList<>());
     }
     

          
A => src/main/java/DBObjects/CalculatedObjects/Interpolater.java +21 -0
@@ 0,0 1,21 @@ 
+
+package DBObjects.CalculatedObjects;
+
+/**
+ *
+ * @author Andrew
+ */
+public class Interpolater {
+    public static double Interpolate(int desiredYear, int startYear, int endYear, double startValue, double endValue) {
+        double annualizedRate = CalculateAnnualizedChange(startYear, endYear, startValue, endValue);
+        int yearsOfChange = desiredYear - startYear;
+        return Math.pow(annualizedRate, yearsOfChange) * startValue;
+    }
+    
+    public static double CalculateAnnualizedChange(int startYear, int endYear, double startValue, double endValue) {
+        int yearDiff = endYear - startYear;
+        double percentageChange = endValue/startValue;  //note the convert to double...
+        double annualizedRate = Math.pow(percentageChange, 1.0/yearDiff);
+        return annualizedRate;
+    }
+}

          
M src/main/java/DBObjects/CountryDB.java +47 -3
@@ 2,6 2,8 @@ 
 package DBObjects;
 
 import DBObjects.CalculatedObjects.CurrencyFigure;
+import DBObjects.CalculatedObjects.Interpolater;
+import exceptions.CurrencyConversionException;
 import java.util.HashMap;
 import java.util.Map;
 

          
@@ 45,8 47,50 @@ public class CountryDB {
             //hack.  it's close enough
             year = 2020;
         }
-        CountryDemographics yearDemographics = demographics.get(year);
-        CurrencyFigure result = new CurrencyFigure(year, yearDemographics.getGNP(), yearDemographics.getCurrency());
-        return result;
+        if (demographics.containsKey(year)) {
+            CountryDemographics yearDemographics = demographics.get(year);
+            CurrencyFigure result = new CurrencyFigure(year, yearDemographics.getGNP(), yearDemographics.getCurrency());
+            return result;
+        }
+        else {
+            //Find the before/after years closest to our year
+            int beforeYear = year - 1;
+            while (beforeYear > 1800) {
+                if (demographics.containsKey(beforeYear)) {
+                    break;
+                }
+                beforeYear--;
+            }
+            int afterYear = year + 1;
+            while (afterYear < 2102) {
+                if (demographics.containsKey(afterYear)) {
+                    break;
+                }
+                afterYear++;
+            }
+            if (beforeYear == 1800 || afterYear == 2102) {
+                //TODO: Exterpolate
+                System.out.println("WARNING: Could not find country demographics for " + this.name + " in " + year);
+                return new CurrencyFigure(year, 1, "USD");
+            }
+            //Get before/after GNP figures in the same currency units
+            CountryDemographics before = demographics.get(beforeYear);
+            CountryDemographics after = demographics.get(afterYear);
+            CurrencyFigure beforeCurrency = new CurrencyFigure(beforeYear, before.getGNP(), before.getCurrency());
+            CurrencyFigure afterCurrency = new CurrencyFigure(afterYear, after.getGNP(), after.getCurrency());
+            if (!after.getCurrency().equals(before.getCurrency())) {
+                //Convert after to before.
+                try {
+                    afterCurrency = afterCurrency.convertTo(before.getCurrency());
+                }
+                catch(CurrencyConversionException ex) {
+                    System.out.println("WARNING: Could not find common currency conversion for " + name + " between " + beforeYear + " and " + afterYear);
+                    return new CurrencyFigure(year, 1, "USD");
+                }
+            }
+            //At this point our units are the same
+            double currencyUnitsInYear = Interpolater.Interpolate(year, beforeYear, afterYear, beforeCurrency.getAmount(), afterCurrency.getAmount());
+            return new CurrencyFigure(year, currencyUnitsInYear, beforeCurrency.getCurrency());
+        }
     }
 }

          
M src/main/java/com/ajtjp/gearCity/Main.java +6 -2
@@ 35,6 35,9 @@ import javax.xml.transform.TransformerFa
 import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
 import org.w3c.dom.Document;
 
 /**

          
@@ 47,11 50,12 @@ public class Main {
     //Prior to that, it might decrease when we load EE1 cities from the DB
     static int nextXMLID = 125;
     
-    final static int[] years = { 1900, 1910, 1920 };
+    final static int[] years = { 1900, 1910, 1920, 1930 };
     
     public static void main(String[] args) throws Exception {
 //        testXMLExport();
-
+        Logger.getRootLogger().setLevel(Level.INFO);
+        BasicConfigurator.configure();
 
         Set<String> citiesAlreadyExisting = new HashSet<>();
 

          
M src/main/java/exceptions/CurrencyConversionException.java +1 -0
@@ 19,6 19,7 @@ public class CurrencyConversionException
         this.source = source;
         this.desired = desired;
         this.year = year;
+        this.reason = reason;
     }
 
     @Override