MER-C / wiki-java

A MediaWiki bot framework in Java
GNU Affero General Public License v3.0
66 stars 58 forks source link

edit() chokes on new MW timestamp handling upon a conflict check #170

Closed PeterBowman closed 5 years ago

PeterBowman commented 5 years ago

I noticed a problem when using the conflict-check signature of edit():

https://github.com/MER-C/wiki-java/blob/08a103769d3eb85fb0ec5b50817ce091b1a977fa/src/org/wikipedia/Wiki.java#L2075

The server returns a response that follows like so:

<?xml version="1.0"?>
<api servedby="mw1290">
    <error code="badtimestamp_starttimestamp" info="Invalid value &quot;2019-11-04T11:29:06.6517352Z&quot; for timestamp parameter &quot;starttimestamp&quot;." xml:space="preserve">See https://pl.wiktionary.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &amp;lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&amp;gt; for notice of API deprecations and breaking changes.</error>
</api>

So, the formatted timestamp reads 2019-11-04T11:29:06.6517352Z. However, https://www.mediawiki.org/wiki/Timestamp states:

On input, the following formats are recognized:

  • A subset of ISO 8601 basic and extended formats:
    • Accuracy to seconds is required. Fractions of a second are supported to microsecond resolution.

Emphasis mine. The timestamp returned by convertToString has an additional digit that exceeds the supported microsecond precision, which I guess is the root of the problem:

https://github.com/MER-C/wiki-java/blob/08a103769d3eb85fb0ec5b50817ce091b1a977fa/src/org/wikipedia/Wiki.java#L8277-L8282

I started noticing this after the breaking change announced at https://lists.wikimedia.org/pipermail/mediawiki-api-announce/2019-June/000146.html (2019-06-21). Not sure whether other components of Wiki.java could be affected. As a temporary workaround, I use the following code in the snippet above, stripping the fractions of second altogether.

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
return date.atZoneSameInstant(ZoneOffset.UTC).format(format);

By the way, even if yyyy-MM-dd'T'HH:mm:ss.nnnnnnZ would seem to stick to only six decimals, Java adds additional stuff with zero-padding beyond the microsecond digit (2019-11-04T11:28:17.650649200+0000) and MW complains again. The trailing +0000 is harmless, e.g. 2019-07-29T07:58:10+0000 works fine.

MER-C commented 5 years ago

Does inserting .truncatedTo(ChronoUnit.MILLIS) before formatting the date fix the problem?

PeterBowman commented 5 years ago

Does inserting .truncatedTo(ChronoUnit.MILLIS) before formatting the date fix the problem?

It definitely does, good catch! It works with ChronoUnit.MICROS, too, and fails with ChronoUnit.NANOS - according to https://www.mediawiki.org/wiki/Timestamp.

See PR: https://github.com/MER-C/wiki-java/pull/171.