Skip to content

Commit

Permalink
Fix ExprFormatTime CCE + Support non-literals (SkriptLang#4664)
Browse files Browse the repository at this point in the history
  • Loading branch information
AyhamAl-Ali authored Jul 18, 2022
1 parent 715a016 commit 58081ab
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 98 deletions.
137 changes: 137 additions & 0 deletions src/main/java/ch/njol/skript/expressions/ExprFormatDate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.expressions;

import java.text.SimpleDateFormat;

import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.VariableString;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.PropertyExpression;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.util.Date;
import ch.njol.skript.util.Getter;
import ch.njol.util.Kleenean;

@Name("Formatted Date")
@Description({
"Converts date to human-readable text format. By default, 'yyyy-MM-dd HH:mm:ss z' (e.g. '2018-03-30 16:03:12 +01') will be used. For reference, see this "
+ "<a href=\"https://en.wikipedia.org/wiki/ISO_8601\">Wikipedia article</a>."
})
@Examples({
"command /date:",
"\ttrigger:",
"\t\tsend \"Full date: %now formatted human-readable%\" to sender",
"\t\tsend \"Short date: %now formatted as \"\"yyyy-MM-dd\"\"%\" to sender"
})
@Since("2.2-dev31, INSERT VERSION (support variables in format)")
public class ExprFormatDate extends PropertyExpression<Date, String> {

private static final SimpleDateFormat DEFAULT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");

static {
Skript.registerExpression(ExprFormatDate.class, String.class, ExpressionType.PROPERTY,
"%dates% formatted [human-readable] [(with|as) %-string%]",
"[human-readable] formatted %dates% [(with|as) %-string%]");
}

@SuppressWarnings("NotNullFieldNotInitialized")
private SimpleDateFormat format;

@SuppressWarnings("NotNullFieldNotInitialized")
private Expression<String> customFormat;

@Override
@SuppressWarnings({"null", "unchecked"})
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
setExpr((Expression<? extends Date>) exprs[0]);
customFormat = (Expression<String>) exprs[1];

boolean isSimpleString = customFormat instanceof VariableString && ((VariableString) customFormat).isSimple();
if (customFormat instanceof Literal || isSimpleString) {
String customFormatValue;
if (isSimpleString) {
customFormatValue = ((VariableString) customFormat).toString(null);
} else {
customFormatValue = ((Literal<String>) customFormat).getSingle();
}

if (customFormatValue != null) {
try {
format = new SimpleDateFormat(customFormatValue);
} catch (IllegalArgumentException e) {
Skript.error("Invalid date format: " + customFormatValue);
return false;
}
}
} else if (customFormat == null) {
format = DEFAULT_FORMAT;
}

return true;
}

@Override
protected String[] get(Event e, Date[] source) {
SimpleDateFormat format;
String formatString;

if (customFormat != null && this.format == null) { // customFormat is not Literal or VariableString
formatString = customFormat.getSingle(e);
if (formatString == null)
return null;

try {
format = new SimpleDateFormat(formatString);
} catch (IllegalArgumentException ex) {
return null;
}
} else {
format = this.format;
}

return get(source, new Getter<String, Date>() {
@Override
public String get(Date date) {
return format.format(new java.util.Date(date.getTimestamp()));
}
});
}

@Override
public Class<? extends String> getReturnType() {
return String.class;
}

@Override
public String toString(@Nullable Event e, boolean debug) {
return getExpr().toString(e, debug) + " formatted as " + (customFormat != null ? customFormat.toString(e, debug)
: (format != null ? format.toPattern() : DEFAULT_FORMAT.toPattern()));
}

}
98 changes: 0 additions & 98 deletions src/main/java/ch/njol/skript/expressions/ExprFormatTime.java

This file was deleted.

20 changes: 20 additions & 0 deletions src/test/skript/tests/regressions/4664-formatted time.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
test "formatted time":
set {_default} to "yyyy-MM-dd HH:mm:ss z"
set {_now} to now

set {_date1} to {_now} formatted
assert {_date1} = {_now} formatted as {_default} with "default date format failed ##1"

set {_date2} to {_now} formatted human-readable
assert {_date2} = {_now} formatted as {_default} with "default date format failed ##2"

set {_date3} to {_now} formatted as "HH:mm"
assert length of {_date3} = 5 with "custom date format failed ##1"

set {_cFormat} to "hh:mm"
set {_date4} to {_now} formatted as {_cFormat}
assert length of {_date4} = 5 with "custom date format failed ##2"

set {_cFormat2} to "i"
set {_date5} to {_now} formatted as {_cFormat2}
assert {_date5} is not set with "custom date format failed ##3"

0 comments on commit 58081ab

Please sign in to comment.