Skip to content

Fix/today-at #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
import io.github.syst3ms.skriptparser.parsing.ParseContext;
import io.github.syst3ms.skriptparser.util.SkriptDate;

import java.time.Duration;

/**
* The current date, the one from yesterday or the one from tomorrow.
*
* @name Now
* @type EXPRESSION
* @pattern (now|yesterday|tomorrow)
* @pattern (yesterday|now|tomorrow)
* @since ALPHA
* @author Mwexim
*/
Expand All @@ -21,7 +23,7 @@ public class ExprDateNow implements Expression<SkriptDate> {
ExprDateNow.class,
SkriptDate.class,
true,
"(0:now|1:yesterday|2:tomorrow)"
"(0:yesterday|1:now|2:tomorrow)"
);
}

Expand All @@ -37,18 +39,18 @@ public boolean init(Expression<?>[] expressions, int matchedPattern, ParseContex
public SkriptDate[] getValues(TriggerContext ctx) {
switch (mark) {
case 0:
return new SkriptDate[] {SkriptDate.now()};
return new SkriptDate[] {SkriptDate.now().minus(Duration.ofDays(1))};
case 1:
return new SkriptDate[] {SkriptDate.of(SkriptDate.now().getTimestamp() - SkriptDate.MILLIS_PER_DAY)};
return new SkriptDate[] {SkriptDate.now()};
case 2:
return new SkriptDate[] {SkriptDate.of(SkriptDate.now().getTimestamp() + SkriptDate.MILLIS_PER_DAY)};
return new SkriptDate[] {SkriptDate.now().plus(Duration.ofDays(1))};
default:
throw new IllegalStateException();
}
}

@Override
public String toString(TriggerContext ctx, boolean debug) {
return new String[] {"now", "yesterday", "tomorrow"}[mark];
return new String[] {"yesterday", "now", "tomorrow"}[mark];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

/**
* The object parsed as a given type.
Expand Down Expand Up @@ -79,7 +78,7 @@ public Object[] getValues(TriggerContext ctx) {
SkriptDate.DATE_LOCALE
);
// We need to parse from the correct time zone.
parseFormat.setTimeZone(TimeZone.getTimeZone(SkriptDate.getZoneId()));
parseFormat.setTimeZone(SkriptDate.getTimeZone());
try {
long timestamp = parseFormat.parse(s).getTime();
return SkriptDate.of(timestamp);
Expand Down
154 changes: 76 additions & 78 deletions src/main/java/io/github/syst3ms/skriptparser/util/SkriptDate.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,159 +7,157 @@
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Locale;
import java.util.TimeZone;

/**
* Represents a date.
* @author Njol
*/
public class SkriptDate implements Comparable<SkriptDate> {
// TODO make a config for this
public final static String DATE_FORMAT = "EEEE dd MMMM yyyy HH:mm:ss.SSS zzzXXX";
public final static Locale DATE_LOCALE = Locale.US;
@SuppressWarnings("FieldMayBeFinal")
private static ZoneId ZONE_ID = ZoneId.systemDefault();
public final static int MILLIS_PER_DAY = 86400000;
private static TimeZone TIME_ZONE = TimeZone.getDefault();

This comment was marked as off-topic.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because then people would be able to change it without any good explanation. There is a public method that returns this field already. Reflection being the requirement means that it normally shouldn't be changed.

Copy link
Contributor

@WeeskyBDW WeeskyBDW Dec 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mea culpa i based this comment on the fact that millis in hours field is public but isn't a big problem if user change it


private long timestamp;

private SkriptDate(long timestamp) {
this.timestamp = timestamp;
}

private SkriptDate(long timestamp, TimeZone zone) {
long offset = zone.getOffset(timestamp);
this.timestamp = timestamp - offset;
this.timestamp = timestamp - zone.getOffset(timestamp);
}

/**
* Get a new {@link SkriptDate} with the current time
* @return new {@link SkriptDate} with the current time
* Creates a new {@link SkriptDate} of the current time.
* @return the date
*/
public static SkriptDate now() {
return SkriptDate.of(System.currentTimeMillis());
return of(System.currentTimeMillis());
}

/**
* Creates a new {@link SkriptDate} with a specific timestamp.
* Note that timestamps are expressed in milliseconds.
* @param timestamp the timestamp
* @return the date
*/
public static SkriptDate of(long timestamp) {
return new SkriptDate(timestamp);
return of(timestamp, TIME_ZONE);
}

/**
* Creates a new {@link SkriptDate} with a specific timestamp.
* The zone offset is taken into account when calculating the
* final timestamp.
* @param timestamp the timestamp
* @param zone the time zone
* @return the date
*/
public static SkriptDate of(long timestamp, TimeZone zone) {
return new SkriptDate(timestamp, zone);
}

/**
* The current day when it started.
* @return the current day like it would just start
* Creates a new {@link SkriptDate} of the current date at midnight.
* @return the date
*/
public static SkriptDate today() {
var localDate = LocalDate.now().atStartOfDay(ZONE_ID);
return SkriptDate.of(localDate.toEpochSecond() * 1000);
var local = LocalDate.now(TIME_ZONE.toZoneId()).atStartOfDay(TIME_ZONE.toZoneId());
return of(local.toEpochSecond() * 1000);
}

public static ZoneId getZoneId() {
return ZONE_ID;
}

@Override
public int compareTo(@Nullable SkriptDate other) {
long d = other == null ? timestamp : timestamp - other.timestamp;
return d < 0 ? -1 : d > 0 ? 1 : 0;
}

public String toString() {
return toString(DATE_FORMAT);
}

/**
* The String representation of this date using a certain format
* @param format the format
* @return the string representation of this date
* @return the default system time zone
*/
public String toString(String format) {
return new SimpleDateFormat(format, DATE_LOCALE).format(new java.util.Date(timestamp));
public static TimeZone getTimeZone() {
return TIME_ZONE;
}

/**
* Get the timestamp of this date.
* @return The timestamp in milliseconds
* Returns the timestamp of this date, in milliseconds.
* @return the timestamp
*/
public long getTimestamp() {
return timestamp;
}

/**
* Get the difference between 2 dates.
* Returns the {@linkplain Duration duration} between the
* given dates.
* @param other the other date
* @return the duration between the dates
* @return the duration
*/
public Duration difference(SkriptDate other) {
return Duration.ofMillis(timestamp - other.getTimestamp()).abs();
}

/**
* Add a {@link Duration} to this date.
* @param span {@link Duration} to add
* Adds a specific {@linkplain Duration duration} to this date.
* A negative duration will subtract instead.
* @param duration the duration
*/
public void add(Duration span) {
timestamp += span.toMillis();
public void add(Duration duration) {
timestamp += duration.toMillis();
}

/**
* Subtract a {@link Duration} from this date.
* @param span {@link Duration} to subtract
* Subtracts a specific {@linkplain Duration duration} from this date.
* A negative duration will add instead.
* @param duration the duration
*/
public void subtract(Duration span) {
timestamp -= span.toMillis();
public void subtract(Duration duration) {
timestamp -= duration.toMillis();
}

/**
* Get a new instance of this date with the added Duration.
* @param span {@link Duration} to add to this Date
* @return new {@link SkriptDate} with the added Duration
* Adds a specific {@linkplain Duration duration} to this date
* and returns the result of this addition.
* A negative duration will subtract instead.
* @param duration the duration
* @return the date
*/
public SkriptDate plus(Duration span) {
return new SkriptDate(timestamp + span.toMillis());
public SkriptDate plus(Duration duration) {
return of(timestamp + duration.toMillis());
}

/**
* Get a new instance of this date with the subtracted Duration.
* @param span {@link Duration} to subtract from this Date
* @return new {@link SkriptDate} with the subtracted Duration
* Subtracts a specific {@linkplain Duration duration} from this date
* and returns the result of this subtraction.
* A negative duration will add instead.
* @param duration the duration
* @return the date
*/
public SkriptDate minus(Duration span) {
return new SkriptDate(timestamp - span.toMillis());
public SkriptDate minus(Duration duration) {
return of(timestamp - duration.toMillis());
}

/**
* Get the {@link LocalDate} instance of this date.
* @return the {@link LocalDate} instance of this date
* Returns this date as a {@link LocalDate}.
* @return the {@link LocalDate} of this date
*/
public LocalDateTime toLocalDateTime() {
Instant in = new java.util.Date(timestamp).toInstant();
return in.atOffset(SkriptDate.ZONE_ID.getRules().getOffset(in)).toLocalDateTime();
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), TIME_ZONE.toZoneId());
}

@Override
public int hashCode() {
int prime = 31;
int result = 1;
result = prime * result + (int) (timestamp ^ (timestamp >>> 32));
return result;
public int compareTo(@Nullable SkriptDate other) {
long d = other == null ? timestamp : timestamp - other.timestamp;
return d < 0 ? -1 : d > 0 ? 1 : 0;
}

public String toString() {
return toString(DATE_FORMAT);
}

/**
* Returns the string representation of this date using a certain format.
* @param format the format
* @return the string representation of this date
*/
public String toString(String format) {
return new SimpleDateFormat(format, DATE_LOCALE).format(new java.util.Date(timestamp));
}

@Override
public boolean equals(@Nullable Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof SkriptDate))
return false;
SkriptDate other = (SkriptDate) obj;
return timestamp == other.timestamp;
return compareTo((SkriptDate) obj) == 0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.lang.reflect.Field;
import java.nio.file.Path;
import java.time.ZoneOffset;
import java.util.TimeZone;

public class TestRegistration {

Expand Down Expand Up @@ -41,16 +42,15 @@ public static void register() {
}
Parser.getMainRegistration().register();

// Now, we need to change some fields to keep all tests consistent.
fields();
}
/*
* Now, we need to change some fields to keep all tests consistent.
*/

public static void fields() {
// ZONE_ID field: all tests need to be executed from the same zone (UTC)
// TIME_ZONE field
try {
Field zoneId = SkriptDate.class.getDeclaredField("ZONE_ID");
zoneId.setAccessible(true);
zoneId.set(null, ZoneOffset.UTC);
Field timeZone = SkriptDate.class.getDeclaredField("TIME_ZONE");
timeZone.setAccessible(true);
timeZone.set(null, TimeZone.getTimeZone(ZoneOffset.UTC));
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
Expand Down