protected static double getWallClockMinutes(WorkflowInstance inst) {
    if (inst == null) {
      return 0.0;
    }

    Date currentDateOrStopTime =
        (inst.getEndDateTimeIsoStr() != null
                && !inst.getEndDateTimeIsoStr().equals("")
                && !inst.getEndDateTimeIsoStr().equals("null"))
            ? safeDateConvert(inst.getEndDateTimeIsoStr())
            : new Date();

    Date workflowStartDateTime = null;

    if (inst.getStartDateTimeIsoStr() == null
        || (inst.getStartDateTimeIsoStr() != null
            && (inst.getStartDateTimeIsoStr().equals("")
                || inst.getStartDateTimeIsoStr().equals("null")))) {
      return 0.0;
    }

    try {
      workflowStartDateTime = DateConvert.isoParse(inst.getStartDateTimeIsoStr());
    } catch (ParseException e) {
      return 0.0;
    }

    long diffMs = currentDateOrStopTime.getTime() - workflowStartDateTime.getTime();
    double diffSecs = (diffMs * 1.0 / 1000.0);
    double diffMins = diffSecs / 60.0;
    return diffMins;
  }
  protected static double getCurrentTaskWallClockMinutes(WorkflowInstance inst) {
    if (inst == null) {
      return 0.0;
    }

    Date currentDateOrStopTime =
        (inst.getCurrentTaskEndDateTimeIsoStr() != null
                && !inst.getCurrentTaskEndDateTimeIsoStr().equals("")
                && !inst.getCurrentTaskEndDateTimeIsoStr().equals("null"))
            ? safeDateConvert(inst.getCurrentTaskEndDateTimeIsoStr())
            : new Date();

    Date workflowTaskStartDateTime = null;

    if (inst.getCurrentTaskStartDateTimeIsoStr() == null
        || (inst.getCurrentTaskStartDateTimeIsoStr() != null
            && (inst.getCurrentTaskStartDateTimeIsoStr().equals("")
                || inst.getCurrentTaskStartDateTimeIsoStr().equals("null")))) {
      return 0.0;
    }

    try {
      workflowTaskStartDateTime = DateConvert.isoParse(inst.getCurrentTaskStartDateTimeIsoStr());
    } catch (ParseException e) {
      return 0.0;
    }

    // should never be in this state, so return 0
    if (workflowTaskStartDateTime.after(currentDateOrStopTime)) {
      LOG.log(
          Level.WARNING,
          "Start date time: ["
              + DateConvert.isoFormat(workflowTaskStartDateTime)
              + " of workflow inst ["
              + inst.getId()
              + "] is AFTER "
              + "End date time: ["
              + DateConvert.isoFormat(currentDateOrStopTime)
              + "] of workflow inst.");
      return 0.0;
    }

    long diffMs = currentDateOrStopTime.getTime() - workflowTaskStartDateTime.getTime();
    double diffSecs = (diffMs * 1.0 / 1000.0);
    double diffMins = diffSecs / 60.0;
    return diffMins;
  }
 private static Date safeDateConvert(String isoTimeStr) {
   try {
     return DateConvert.isoParse(isoTimeStr);
   } catch (Exception ignore) {
     ignore.printStackTrace();
     return null;
   }
 }