Make input more lenient. Allow specifying TZ other than UTC.

Also remove 'none' and cleanup LocationFlag.
This commit is contained in:
wizjany 2019-03-30 20:07:35 -04:00
parent 9c5eee90da
commit 874e429779
2 changed files with 26 additions and 9 deletions

View File

@ -47,9 +47,9 @@ public Location parseInput(FlagContext context) throws InvalidFlagFormat {
Location loc = null; Location loc = null;
if ("here".equalsIgnoreCase(input)) { if ("here".equalsIgnoreCase(input)) {
loc = player.getLocation(); Location playerLoc = player.getLocation();
} else if ("none".equalsIgnoreCase(input)) { loc = new LazyLocation(((World) playerLoc.getExtent()).getName(),
return null; loc.toVector(), loc.getYaw(), loc.getPitch());
} else { } else {
String[] split = input.split(","); String[] split = input.split(",");
if (split.length >= 3) { if (split.length >= 3) {

View File

@ -21,15 +21,24 @@
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
/** /**
* Stores a timestamp. * Stores a timestamp.
*/ */
public class TimestampFlag extends Flag<Instant> { public class TimestampFlag extends Flag<Instant> {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneOffset.UTC); private static final DateTimeFormatter SERIALIZER = DateTimeFormatter.ISO_DATE_TIME.withZone(ZoneOffset.UTC);
private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.optionalStart().appendOffsetId()
.toFormatter();
public TimestampFlag(String name, @Nullable RegionGroup defaultGroup) { public TimestampFlag(String name, @Nullable RegionGroup defaultGroup) {
super(name, defaultGroup); super(name, defaultGroup);
} }
@ -41,12 +50,20 @@ public TimestampFlag(String name) {
@Override @Override
public Instant parseInput(FlagContext context) throws InvalidFlagFormat { public Instant parseInput(FlagContext context) throws InvalidFlagFormat {
String input = context.getUserInput(); String input = context.getUserInput();
if("now".equalsIgnoreCase(input)) { if ("now".equalsIgnoreCase(input)) {
return Instant.now(); return Instant.now();
} else { } else {
try { try {
return Instant.from(FORMATTER.parse(input)); TemporalAccessor parsed = PARSER.parseBest(input, ZonedDateTime::from, LocalDateTime::from);
} catch(DateTimeParseException ignored) { // convert whatever input into UTC for storage
if (parsed instanceof LocalDateTime) {
return ((LocalDateTime) parsed).atZone(ZoneOffset.UTC).toInstant();
} else if (parsed instanceof ZonedDateTime) {
return ((ZonedDateTime) parsed).toInstant();
} else {
throw new InvalidFlagFormat("Unrecognized input.");
}
} catch (DateTimeParseException ignored) {
throw new InvalidFlagFormat("Expected 'now' or ISO 8601 formatted input."); throw new InvalidFlagFormat("Expected 'now' or ISO 8601 formatted input.");
} }
} }
@ -56,7 +73,7 @@ public Instant parseInput(FlagContext context) throws InvalidFlagFormat {
public Instant unmarshal(@Nullable Object o) { public Instant unmarshal(@Nullable Object o) {
if (o instanceof String) { if (o instanceof String) {
try { try {
return Instant.from(FORMATTER.parse((String) o)); return Instant.from(SERIALIZER.parse((String) o));
} catch(DateTimeParseException ignored) { } catch(DateTimeParseException ignored) {
return null; return null;
} }
@ -66,6 +83,6 @@ public Instant unmarshal(@Nullable Object o) {
@Override @Override
public Object marshal(Instant o) { public Object marshal(Instant o) {
return FORMATTER.format(o); return SERIALIZER.format(o);
} }
} }