private void setTimeZone(String line) throws JBookTraderException {
   String timeZone = line.substring(line.indexOf('=') + 1);
   TimeZone tz = TimeZone.getTimeZone(timeZone);
   if (!tz.getID().equals(timeZone)) {
     String msg =
         "The specified time zone " + "\"" + timeZone + "\"" + " does not exist." + LINE_SEP;
     msg += "Examples of valid time zones: " + " America/New_York, Europe/London, Asia/Singapore.";
     throw new JBookTraderException(msg);
   }
   sdf = new SimpleDateFormat("MMddyyHHmmss");
   // Enforce strict interpretation of date and time formats
   sdf.setLenient(false);
   sdf.setTimeZone(tz);
 }
  private MarketSnapshot toMarketDepth(String line) throws JBookTraderException, ParseException {
    List<String> tokens = fastSplit(line);

    if (tokens.size() != COLUMNS) {
      String msg = "The line should contain exactly " + COLUMNS + " comma-separated columns.";
      throw new JBookTraderException(msg);
    }

    String dateTime = tokens.get(0) + tokens.get(1);
    String dateTimeWithoutSeconds = dateTime.substring(0, 10);

    if (dateTimeWithoutSeconds.equals(previousDateTimeWithoutSeconds)) {
      // only seconds need to be set
      int milliSeconds = 1000 * Integer.parseInt(dateTime.substring(10));
      long previousMilliSeconds = previousTime % 60000;
      time = previousTime + (milliSeconds - previousMilliSeconds);
    } else {
      time = sdf.parse(dateTime).getTime();
      previousDateTimeWithoutSeconds = dateTimeWithoutSeconds;
    }

    if (time <= previousTime) {
      String msg =
          "Timestamp of this line is before or the same as the timestamp of the previous line.";
      throw new JBookTraderException(msg);
    }

    double balance = Double.parseDouble(tokens.get(2));
    double price = Double.parseDouble(tokens.get(3));
    int volume = Integer.parseInt(tokens.get(4));
    return new MarketSnapshot(time, balance, price, volume);
  }