Skip to content

Commit 45fd724

Browse files
committed
A slightly cleaner fix #12354
1 parent bae1692 commit 45fd724

1 file changed

Lines changed: 21 additions & 1 deletion

File tree

src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,27 @@ public Command<DatasetVersion> handleLatestPublished() {
488488
}
489489

490490
protected void validateInternalTimestampIsNotOutdated(DvObject dvObject, String sourceLastUpdateTime) throws WrappedResponse {
491-
Date date = sourceLastUpdateTime != null ? DateUtil.parseDate(sourceLastUpdateTime.replaceFirst("Z$", "+0000"), "yyyy-MM-dd'T'HH:mm:ssZ") : null;
491+
// The timestamp string must always be in UTC, ISO 8601-formatted
492+
// for example: 2026-04-22T14:30:00Z. This is explicitly specified in the
493+
// API guide.
494+
//
495+
// In the intended workflow, the clients will be reusing the last update
496+
// timestamps obtained from the output of other Dataverse APIs, such as
497+
// /versions and /files, where they are always in that form, regardless
498+
// of the actual time zone the server lives in.
499+
//
500+
// For consistency, we do not want to accept any other formats or timezones,
501+
// and will reject anything that does not match "yyyy-MM-dd'T'HH:mm:ss'Z'".
502+
// For that reason there is an explicit check added for .endsWith("Z").
503+
// The "X" in the parsing format string will recognize literal 'Z' as "+0000",
504+
// but it would also accept other ISO 8601 timezones, such as "+0400" for
505+
// EDT, etc. In theory, we could accept all these other notations - in
506+
// case the client decided to convert the UTC timestamp they received from
507+
// Dataverse into that... but there is really no good reason to encourage
508+
// that.
509+
Date date = sourceLastUpdateTime != null && sourceLastUpdateTime.endsWith("Z")
510+
? DateUtil.parseDate(sourceLastUpdateTime, "yyyy-MM-dd'T'HH:mm:ssX")
511+
: null;
492512
if (date == null) {
493513
throw new WrappedResponse(
494514
badRequest(BundleUtil.getStringFromBundle("jsonparser.error.parsing.date", Collections.singletonList(sourceLastUpdateTime)))

0 commit comments

Comments
 (0)