{"record":{"id":"377a0c5c95ea96da","repo":"binarywang/WxJava","slug":"error-377a0c","errorCode":null,"errorMessage":"获取记录时间跨度不超过一个月","messagePattern":"获取记录时间跨度不超过一个月","errorType":"validation","errorClass":"WxRuntimeException","httpStatus":null,"severity":"warning","filePath":"weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java","lineNumber":55,"sourceCode":"  public String apply(WxCpOaApplyEventRequest request) throws WxErrorException {\n    String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(APPLY_EVENT),\n      request.toJson());\n    return GsonParser.parse(responseContent).get(\"sp_no\").getAsString();\n  }\n\n  @Override\n  public List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, @NonNull Date startTime,\n                                              @NonNull Date endTime,\n                                              List<String> userIdList) throws WxErrorException {\n    if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) {\n      throw new WxRuntimeException(\"用户列表不能为空，不超过 \" + USER_IDS_LIMIT + \" 个，若用户超过 \" + USER_IDS_LIMIT + \" 个，请分批获取\");\n    }\n\n    long endTimestamp = endTime.getTime() / 1000L;\n    long startTimestamp = startTime.getTime() / 1000L;\n\n    if (endTimestamp - startTimestamp < 0 || endTimestamp - startTimestamp > MONTH_SECONDS) {\n      throw new WxRuntimeException(\"获取记录时间跨度不超过一个月\");\n    }\n\n    JsonObject jsonObject = new JsonObject();\n    JsonArray jsonArray = new JsonArray();\n\n    jsonObject.addProperty(\"opencheckindatatype\", openCheckinDataType);\n    jsonObject.addProperty(\"starttime\", startTimestamp);\n    jsonObject.addProperty(\"endtime\", endTimestamp);\n\n    for (String userid : userIdList) {\n      jsonArray.add(userid);\n    }\n\n    jsonObject.add(\"useridlist\", jsonArray);\n\n    final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CHECKIN_DATA);\n    String responseContent = this.mainService.post(url, jsonObject.toString());\n    JsonObject tmpJson = GsonParser.parse(responseContent);","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java#L37-L73","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Split wide date ranges into multiple calls each spanning at most 30 days","Validate that endTime is after startTime before calling","Use a helper that chunks Date ranges into 30-day windows and aggregates results"],"exampleFix":"// before\nList<WxCpCheckinData> data = oaService.getCheckinData(type, quarterStart, quarterEnd); // 90 days\n\n// after — chunk into 30-day windows\nList<WxCpCheckinData> allData = new ArrayList<>();\nDate windowStart = quarterStart;\nwhile (windowStart.before(quarterEnd)) {\n  Date windowEnd = new Date(Math.min(windowStart.getTime() + 30L * 24 * 3600 * 1000, quarterEnd.getTime()));\n  allData.addAll(oaService.getCheckinData(type, windowStart, windowEnd, userIds));\n  windowStart = new Date(windowEnd.getTime() + 1000);\n}","handlingStrategy":"validation","validationCode":"// Validate date range before calling\nlong diffSeconds = (endTime.getTime() - startTime.getTime()) / 1000;\nif (diffSeconds < 0) {\n  throw new IllegalArgumentException(\"endTime 必须晚于 startTime\");\n}\nif (diffSeconds > 31 * 24 * 3600) {\n  throw new IllegalArgumentException(\"时间跨度不能超过 31 天，当前: \" + (diffSeconds / 86400) + \" 天\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate date ranges at the caller layer with a shared utility","Chunk wide ranges into 30-day windows before calling OA APIs","Use DatePicker constraints in the UI to prevent users from selecting ranges over 30 days"],"tags":["wechat-cp","oa","checkin","validation","date-range"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}