Skip to content

Commit cfaeb78

Browse files
author
Dynxsty
authored
Merge pull request #7 from Java-Discord/andrew/time_fix
Improved TimeUtils
2 parents c389836 + 7fa19f1 commit cfaeb78

File tree

8 files changed

+111
-30
lines changed

8 files changed

+111
-30
lines changed

.github/workflows/gradle.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ jobs:
2424
- name: Grant execute permission for gradlew
2525
run: chmod +x gradlew
2626
- name: Build with Gradle
27-
run: ./gradlew build
27+
run: ./gradlew build
28+
- name: Test with Gradle
29+
run: ./gradlew test

src/main/java/com/javadiscord/javabot/commands/user_commands/Profile.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
import org.bson.Document;
1616

1717
import java.awt.*;
18-
import java.time.Duration;
19-
import java.time.OffsetDateTime;
2018
import java.util.List;
2119

2220
import static com.javadiscord.javabot.events.Startup.mongoClient;
@@ -148,8 +146,9 @@ public static void exCommand(CommandEvent event) {
148146
int qotwCount = Database.getMemberInt(collection, member, "qotwpoints");
149147
int warnCount = Database.getMemberInt(collection, member, "warns");
150148

151-
String joinDiff = " (" + TimeUtils.formatDurationToNow(member.getTimeJoined()) + ")";
152-
String createDiff = " (" + TimeUtils.formatDurationToNow(member.getTimeCreated()) + ")";
149+
TimeUtils tu = new TimeUtils();
150+
String joinDiff = " (" + tu.formatDurationToNow(member.getTimeJoined()) + ")";
151+
String createDiff = " (" + tu.formatDurationToNow(member.getTimeCreated()) + ")";
153152

154153
EmbedBuilder eb = new EmbedBuilder()
155154
.setTitle(statusEmote + " " + member.getUser().getAsTag() + " " + botBadge + boostBadge + badges)
@@ -283,8 +282,9 @@ public static void exCommand(SlashCommandEvent event, Member member) {
283282
int qotwCount = Database.getMemberInt(collection, member, "qotwpoints");
284283
int warnCount = Database.getMemberInt(collection, member, "warns");
285284

286-
String joinDiff = " (" + TimeUtils.formatDurationToNow(member.getTimeJoined()) + ")";
287-
String createDiff = " (" + TimeUtils.formatDurationToNow(member.getTimeCreated()) + ")";
285+
TimeUtils tu = new TimeUtils();
286+
String joinDiff = " (" + tu.formatDurationToNow(member.getTimeJoined()) + ")";
287+
String createDiff = " (" + tu.formatDurationToNow(member.getTimeCreated()) + ")";
288288

289289
EmbedBuilder eb = new EmbedBuilder()
290290
.setTitle(statusEmote + " " + member.getUser().getAsTag() + " " + botBadge + boostBadge + badges)

src/main/java/com/javadiscord/javabot/commands/user_commands/ServerInfo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public static void exCommand (CommandEvent event) {
2424
long channelCount = event.getGuild().getChannels().stream().count() - catCount;
2525

2626
String guildDate = event.getGuild().getTimeCreated().format(TimeUtils.STANDARD_FORMATTER);
27-
String createdDiff = " (" + TimeUtils.formatDurationToNow(event.getGuild().getTimeCreated()) + ")";
27+
String createdDiff = " (" + new TimeUtils().formatDurationToNow(event.getGuild().getTimeCreated()) + ")";
2828

2929
EmbedBuilder eb = new EmbedBuilder()
3030
.setColor(new Color(0x2F3136))
@@ -59,7 +59,7 @@ public static void exCommand (SlashCommandEvent event) {
5959
long channelCount = event.getGuild().getChannels().stream().count() - catCount;
6060

6161
String guildDate = event.getGuild().getTimeCreated().format(TimeUtils.STANDARD_FORMATTER);
62-
String createdDiff = " (" + TimeUtils.formatDurationToNow(event.getGuild().getTimeCreated()) + ")";
62+
String createdDiff = " (" + new TimeUtils().formatDurationToNow(event.getGuild().getTimeCreated()) + ")";
6363

6464
EmbedBuilder eb = new EmbedBuilder()
6565
.setColor(new Color(0x2F3136))

src/main/java/com/javadiscord/javabot/events/UserJoin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ public void onGuildMemberJoin(GuildMemberJoinEvent event) {
198198
user.openPrivateChannel().complete().sendMessage(ServerLock.lockEmbed(event.getGuild())).queue();
199199
event.getMember().kick().complete();
200200

201-
String diff = TimeUtils.formatDurationToNow(event.getMember().getTimeCreated());
201+
String diff = new TimeUtils().formatDurationToNow(event.getMember().getTimeCreated());
202202
welcomeChannel.sendMessage("**" + event.getMember().getUser().getAsTag() + "**" + " (" + diff + " old) tried to join this server.").queue();
203203

204204
}

src/main/java/com/javadiscord/javabot/other/ServerLock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public static void incrementLock(GuildMemberJoinEvent event, User user) {
5151
Database.queryConfigInt(event.getGuild().getId(), "lockcount", lockCount);
5252

5353
String timeCreated = user.getTimeCreated().format(TimeUtils.STANDARD_FORMATTER);
54-
String createDiff = " (" + TimeUtils.formatDurationToNow(user.getTimeCreated()) + " ago)";
54+
String createDiff = " (" + new TimeUtils().formatDurationToNow(user.getTimeCreated()) + " ago)";
5555

5656
EmbedBuilder eb = new EmbedBuilder()
5757
.setColor(Constants.GRAY)
Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.javadiscord.javabot.other;
22

3+
import java.time.Clock;
34
import java.time.Duration;
45
import java.time.OffsetDateTime;
56
import java.time.format.DateTimeFormatter;
@@ -17,14 +18,34 @@ public class TimeUtils {
1718
STANDARD_FORMATTER = DateTimeFormatter.ofPattern("EEE',' dd/MM/yyyy',' HH:mm", Locale.ENGLISH);
1819
}
1920

21+
private final Clock clock;
22+
23+
public TimeUtils() {
24+
this(Clock.systemDefaultZone());
25+
}
26+
27+
public TimeUtils(Clock clock) {
28+
this.clock = clock;
29+
}
30+
2031
/**
2132
* Returns the duration between the given time and now, respecting time zone
2233
* information.
2334
* @param time The time to get the duration to.
2435
* @return A duration between the given time and now.
2536
*/
26-
public static Duration durationToNow(OffsetDateTime time) {
27-
return Duration.between(time, OffsetDateTime.now(time.getOffset()));
37+
public Duration durationToNow(OffsetDateTime time) {
38+
return Duration.between(time, this.clock.instant().atOffset(time.getOffset()));
39+
}
40+
41+
/**
42+
* Shortcut to get a formatted duration string representing the duration
43+
* from the given time to now.
44+
* @param time The time to use.
45+
* @return A string representing the duration.
46+
*/
47+
public String formatDurationToNow(OffsetDateTime time) {
48+
return formatDuration(durationToNow(time));
2849
}
2950

3051
/**
@@ -33,28 +54,34 @@ public static Duration durationToNow(OffsetDateTime time) {
3354
* @return A string representing a human-readable duration.
3455
*/
3556
public static String formatDuration(Duration duration) {
36-
if (duration.toDays() > 365) {
37-
return String.format("%d years, %d days", duration.toDays() / 365, duration.toDays() % 365);
38-
} else if (duration.toDays() > 2) {
39-
return String.format("%d days", duration.toDays());
40-
} else if (duration.toHours() > 2) {
41-
return String.format("%d hours", duration.toHours());
42-
} else if (duration.toMinutes() > 2){
43-
return String.format("%d minutes", duration.toMinutes());
44-
} else if (duration.toSeconds() > 2) {
45-
return String.format("%d seconds", duration.toSeconds());
57+
if (duration.toDays() >= 365) {
58+
long years = duration.toDays() / 365;
59+
long days = duration.toDays() % 365;
60+
StringBuilder sb = new StringBuilder(pluralize("year", "years", years));
61+
if (days > 0) sb.append(", ").append(pluralize("day", "days", days));
62+
return sb.toString();
63+
} else if (duration.toDays() > 0) {
64+
return pluralize("day", "days", duration.toDays());
65+
} else if (duration.toHours() > 0) {
66+
return pluralize("hour", "hours", duration.toHours());
67+
} else if (duration.toMinutes() > 0){
68+
return pluralize("minute", "minutes", duration.toMinutes());
69+
} else if (duration.toSeconds() > 0) {
70+
return pluralize("second", "seconds", duration.toSeconds());
4671
} else {
47-
return String.format("%d milliseconds", duration.toMillis());
72+
return pluralize("millisecond", "milliseconds", duration.toMillis());
4873
}
4974
}
5075

5176
/**
52-
* Shortcut to get a formatted duration string representing the duration
53-
* from the given time to now.
54-
* @param time The time to use.
55-
* @return A string representing the duration.
77+
* Formats an integer number with a suffix that agrees with the plurality of
78+
* the number. For example, this can produce "1 day" and "2 days".
79+
* @param single The singular form of the suffix.
80+
* @param plural The plural form of the suffix.
81+
* @param count The value to show.
82+
* @return A string representation that respects plurality.
5683
*/
57-
public static String formatDurationToNow(OffsetDateTime time) {
58-
return formatDuration(durationToNow(time));
84+
private static String pluralize(String single, String plural, long count) {
85+
return count + " " + (count == 1 ? single : plural);
5986
}
6087
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.javadiscord.javabot.other;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.time.*;
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
import static org.junit.jupiter.api.Assertions.assertEquals;
10+
11+
/**
12+
* Tests the functionality of the {@link TimeUtils} class.
13+
*/
14+
public class TimeUtilsTest {
15+
@Test
16+
public void testDurationToNow() {
17+
OffsetDateTime now = OffsetDateTime.of(2020, 6, 1, 10, 16, 45, 0, ZoneOffset.UTC);
18+
TimeUtils tu = new TimeUtils(Clock.fixed(now.toInstant(), ZoneOffset.UTC));
19+
assertEquals(3, tu.durationToNow(now.minusDays(3)).toDays());
20+
assertEquals(2, tu.durationToNow(now.minusHours(2).atZoneSameInstant(ZoneId.of("EST", ZoneId.SHORT_IDS)).toOffsetDateTime()).toHours());
21+
}
22+
23+
@Test
24+
public void testFormatDuration() {
25+
Map<Duration, String> cases = new HashMap<>();
26+
cases.put(Duration.ofDays(0), "0 milliseconds");
27+
cases.put(Duration.ofDays(1), "1 day");
28+
cases.put(Duration.ofDays(2), "2 days");
29+
cases.put(Duration.ofMillis(2), "2 milliseconds");
30+
cases.put(Duration.ofMillis(1), "1 millisecond");
31+
cases.put(Duration.ofSeconds(1), "1 second");
32+
cases.put(Duration.ofSeconds(3), "3 seconds");
33+
cases.put(Duration.ofMinutes(1), "1 minute");
34+
cases.put(Duration.ofMinutes(45), "45 minutes");
35+
cases.put(Duration.ofHours(1), "1 hour");
36+
cases.put(Duration.ofHours(2), "2 hours");
37+
cases.put(Duration.ofDays(366), "1 year, 1 day");
38+
cases.put(Duration.ofDays(365), "1 year");
39+
cases.put(Duration.ofDays(730), "2 years");
40+
cases.put(Duration.ofDays(731), "2 years, 1 day");
41+
cases.put(Duration.ofDays(732), "2 years, 2 days");
42+
43+
for (var c : cases.entrySet()) {
44+
String actual = TimeUtils.formatDuration(c.getKey());
45+
assertEquals(c.getValue(), actual);
46+
}
47+
}
48+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/**
2+
* This package contains all tests for the JavaBot.
3+
*/
4+
package com.javadiscord.javabot;

0 commit comments

Comments
 (0)