The date format issues you’re experiencing are due to inconsistent date handling across Trackwise API endpoints and the lack of clear documentation on API request payload standards. Let me provide a comprehensive solution for your automated report scheduling.
Date Format Validation in TW 9.1:
The compliance report export API specifically requires dates in “yyyy-MM-dd HH:mm:ss” format without timezone information. The API interprets all dates in the Trackwise server’s configured timezone, which can cause confusion if your automation runs in a different timezone.
Correct Request Format:
{
"reportType": "AUDIT_SUMMARY",
"startDate": "2025-03-01 00:00:00",
"endDate": "2025-03-31 23:59:59",
"format": "PDF",
"includeAttachments": false
}
Key Requirements:
- Use 24-hour time format (HH not hh)
- Include seconds (ss) even if zero
- No timezone indicators (Z, +00:00, etc.)
- No milliseconds
- Space between date and time (not T)
API Request Payload Standards:
Here’s the complete specification for compliance report exports:
Required Fields:
reportType: String enum (AUDIT_SUMMARY, DEVIATION_REPORT, CAPA_STATUS, etc.)
startDate: String in yyyy-MM-dd HH:mm:ss format
endDate: String in yyyy-MM-dd HH:mm:ss format
Optional Fields:
format: String enum (PDF, EXCEL, CSV) - defaults to PDF
filters: Object with report-specific filter criteria
includeAttachments: Boolean - defaults to false
emailRecipients: Array of email addresses for automatic delivery
Automated Report Scheduling Implementation:
Here’s a robust implementation for your automation:
public class ComplianceReportScheduler {
private static final DateTimeFormatter TW_DATE_FORMAT =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public void exportMonthlyReport(YearMonth reportMonth) {
// Calculate date range in server timezone
ZoneId serverZone = ZoneId.of("America/New_York"); // Your TW server timezone
LocalDateTime startOfMonth = reportMonth.atDay(1).atStartOfDay();
LocalDateTime endOfMonth = reportMonth.atEndOfMonth().atTime(23, 59, 59);
String startDate = startOfMonth.format(TW_DATE_FORMAT);
String endDate = endOfMonth.format(TW_DATE_FORMAT);
// Build request
JsonObject payload = new JsonObject();
payload.addProperty("reportType", "AUDIT_SUMMARY");
payload.addProperty("startDate", startDate);
payload.addProperty("endDate", endDate);
payload.addProperty("format", "PDF");
try {
HttpResponse response = apiClient.post(
"/api/compliance/reports/export",
payload.toString()
);
if (response.getStatusCode() == 200) {
processReport(response.getBody());
} else {
handleError(response);
}
} catch (Exception e) {
logger.error("Report export failed", e);
throw new ReportingException("Failed to export compliance report", e);
}
}
}
Timezone Handling:
This is critical for automated scheduling. If your automation runs in UTC but your Trackwise server is in EST:
// Convert your automation's timezone to server timezone
ZonedDateTime automationTime = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime serverTime = automationTime.withZoneSameInstant(
ZoneId.of("America/New_York")
);
String formattedDate = serverTime.format(TW_DATE_FORMAT);
Error Handling for Date Validation:
private void handleError(HttpResponse response) {
if (response.getBody().contains("Invalid date format")) {
logger.error("Date format validation failed. Sent: {} Expected: yyyy-MM-dd HH:mm:ss",
payload.get("startDate"));
// Log the exact payload for debugging
logger.debug("Full request payload: {}", payload.toString());
}
}
Testing Different Report Types:
Some report types have restrictions on date ranges:
public void validateReportType(String reportType, LocalDate startDate, LocalDate endDate) {
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
switch (reportType) {
case "AUDIT_SUMMARY":
// Supports up to 12 months
if (daysBetween > 365) {
throw new ValidationException("Date range exceeds 12 months");
}
break;
case "DEVIATION_REPORT":
// Supports up to 3 months
if (daysBetween > 90) {
throw new ValidationException("Date range exceeds 3 months");
}
break;
}
}
Automated Report Scheduling Configuration:
For scheduled jobs, use a configuration file to manage report parameters:
{
"schedules": [
{
"reportType": "AUDIT_SUMMARY",
"frequency": "MONTHLY",
"dayOfMonth": 1,
"time": "08:00:00",
"timezone": "America/New_York",
"lookbackPeriod": "PREVIOUS_MONTH",
"format": "PDF",
"recipients": ["compliance@company.com"]
}
]
}
This configuration-driven approach eliminates hardcoded dates and makes your automation more maintainable.
Final Recommendations:
- Always format dates in the server’s timezone using yyyy-MM-dd HH:mm:ss
- Validate date ranges before sending to API to avoid unnecessary failures
- Log the exact payload when date validation fails for troubleshooting
- Implement retry logic with exponential backoff for transient failures
- Store successful report exports with their parameters for audit trail
This complete implementation should resolve your reporting delays and enable reliable automated report scheduling.