binarywang/WxJava · warning · WxRuntimeException

获取记录时间跨度不超过一个月

Error message

获取记录时间跨度不超过一个月

What it means

Thrown (as unchecked WxRuntimeException) by getCheckinData() when the time range between startTime and endTime exceeds 31 days (MONTH_SECONDS = 31 * 24 * 60 * 60) or when endTime is before startTime. WeChat's checkin-data API enforces a maximum query window of one month.

Source

Thrown at weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java:55

  public String apply(WxCpOaApplyEventRequest request) throws WxErrorException {
    String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(APPLY_EVENT),
      request.toJson());
    return GsonParser.parse(responseContent).get("sp_no").getAsString();
  }

  @Override
  public List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, @NonNull Date startTime,
                                              @NonNull Date endTime,
                                              List<String> userIdList) throws WxErrorException {
    if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) {
      throw new WxRuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取");
    }

    long endTimestamp = endTime.getTime() / 1000L;
    long startTimestamp = startTime.getTime() / 1000L;

    if (endTimestamp - startTimestamp < 0 || endTimestamp - startTimestamp > MONTH_SECONDS) {
      throw new WxRuntimeException("获取记录时间跨度不超过一个月");
    }

    JsonObject jsonObject = new JsonObject();
    JsonArray jsonArray = new JsonArray();

    jsonObject.addProperty("opencheckindatatype", openCheckinDataType);
    jsonObject.addProperty("starttime", startTimestamp);
    jsonObject.addProperty("endtime", endTimestamp);

    for (String userid : userIdList) {
      jsonArray.add(userid);
    }

    jsonObject.add("useridlist", jsonArray);

    final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CHECKIN_DATA);
    String responseContent = this.mainService.post(url, jsonObject.toString());
    JsonObject tmpJson = GsonParser.parse(responseContent);

View on GitHub (pinned to 1c43293a3c)

Solutions

  1. Split wide date ranges into multiple calls each spanning at most 30 days
  2. Validate that endTime is after startTime before calling
  3. Use a helper that chunks Date ranges into 30-day windows and aggregates results

Example fix

// before
List<WxCpCheckinData> data = oaService.getCheckinData(type, quarterStart, quarterEnd); // 90 days

// after — chunk into 30-day windows
List<WxCpCheckinData> allData = new ArrayList<>();
Date windowStart = quarterStart;
while (windowStart.before(quarterEnd)) {
  Date windowEnd = new Date(Math.min(windowStart.getTime() + 30L * 24 * 3600 * 1000, quarterEnd.getTime()));
  allData.addAll(oaService.getCheckinData(type, windowStart, windowEnd, userIds));
  windowStart = new Date(windowEnd.getTime() + 1000);
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate date range before calling
long diffSeconds = (endTime.getTime() - startTime.getTime()) / 1000;
if (diffSeconds < 0) {
  throw new IllegalArgumentException("endTime 必须晚于 startTime");
}
if (diffSeconds > 31 * 24 * 3600) {
  throw new IllegalArgumentException("时间跨度不能超过 31 天,当前: " + (diffSeconds / 86400) + " 天");
}

Prevention

When it happens

Trigger: Passing startTime and endTime where the difference is negative (endTime before startTime) or greater than 31 days (2,678,400 seconds). The check is `endTimestamp - startTimestamp < 0 || endTimestamp - startTimestamp > MONTH_SECONDS`.

Common situations: Querying a full quarter or year of checkin data in one call; accidentally swapping start and end parameters; using a date picker that defaults to a wide range.

Related errors


AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14). Data as JSON: /api/errors/377a0c5c95ea96da. Report an issue: GitHub.