code: public static boolean reallyDifferent(JsonNode source, JsonNode dest, boolean ignoreTimestampMSDiffs) {
          if (source == null || source instanceof NullNode) {
              if (dest == null || dest instanceof NullNode) {
                  return false;
              } else {
                  return true;
              }
          } else if (dest == null || dest instanceof NullNode) {
              return true;
          } else {
              String s1 = source.asText();
              String s2 = dest.asText();
              if (s1.equals(s2)) {
                  return false;
              }
  
              // They are different strings
              // Do they look like dates?
              Date d1;
              Date d2;
              DateFormat fmt = ClientConstants.getDateFormat();
              try {
                  d1 = fmt.parse(s1);
              } catch (Exception e) {
                  return true;
              }
              try {
                  d2 = fmt.parse(s2);
              } catch (Exception e) {
                  return true;
              }
  
              if (ignoreTimestampMSDiffs) {
                  long d1ms = 1000 * (d1.getTime() / 1000);
                  long d2ms = 1000 * (d2.getTime() / 1000);
  
                  return d1ms != d2ms;
              } else {
                  return d1.getTime() != d2.getTime();
              }
          }
      }
docs: This stupidity is required because data types of the source and dest
  might be different, but they might have the same value. Like, a number
  represented as string in one system could be an int in another. That is
  valid, but JSON comparison fails for that, so we check if the two nodes
  are *really* different, meaning: for anything but dates, check string
  equivalence. For dates, normalize by TZ and check.