diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampConfig.java
index da1bf222ce..fda97b0941 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampConfig.java
@@ -35,6 +35,7 @@ public interface TimestampConfig extends Config
@ConfigItem(
keyName = "opaqueTimestamp",
name = "Timestamps (opaque)",
+ position = 1,
description = "Colour of Timestamps from the Timestamps plugin (opaque)"
)
Color opaqueTimestamp();
@@ -42,7 +43,26 @@ public interface TimestampConfig extends Config
@ConfigItem(
keyName = "transparentTimestamp",
name = "Timestamps (transparent)",
+ position = 2,
description = "Colour of Timestamps from the Timestamps plugin (transparent)"
)
Color transparentTimestamp();
+
+ @ConfigItem(
+ keyName = "format",
+ name = "Timestamp Format",
+ position = 3,
+ description = "Customize your timestamp format by using the following characters
" +
+ "'yyyy' : year
" +
+ "'MM' : month
" +
+ "'dd' : day
" +
+ "'HH' : hour in 24 hour format
" +
+ "'hh' : hour in 12 hour format
" +
+ "'mm' : minute
" +
+ "'ss' : second"
+ )
+ default String timestampFormat()
+ {
+ return "[HH:mm]";
+ }
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java
index baf0f5f232..4379d37844 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java
@@ -27,14 +27,17 @@ package net.runelite.client.plugins.timestamp;
import com.google.inject.Provides;
import java.awt.Color;
+import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
-import java.time.temporal.ChronoField;
+import java.util.Date;
import javax.inject.Inject;
+import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.MessageNode;
import net.runelite.api.Varbits;
+import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
@@ -56,12 +59,36 @@ public class TimestampPlugin extends Plugin
@Inject
private TimestampConfig config;
+ @Getter
+ private SimpleDateFormat formatter;
+
@Provides
public TimestampConfig provideConfig(final ConfigManager configManager)
{
return configManager.getConfig(TimestampConfig.class);
}
+ @Override
+ protected void startUp() throws Exception
+ {
+ updateFormatter();
+ }
+
+ @Override
+ protected void shutDown() throws Exception
+ {
+ formatter = null;
+ }
+
+ @Subscribe
+ public void onConfigChanged(ConfigChanged event)
+ {
+ if (event.getGroup().equals("timestamp") && event.getKey().equals("format"))
+ {
+ updateFormatter();
+ }
+ }
+
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent event)
{
@@ -80,13 +107,7 @@ public class TimestampPlugin extends Plugin
MessageNode messageNode = (MessageNode) client.getMessages().get(messageId);
- final ZonedDateTime time = ZonedDateTime.ofInstant(
- Instant.ofEpochSecond(messageNode.getTimestamp()), ZoneId.systemDefault());
-
- final String dateFormat = time.get(ChronoField.HOUR_OF_DAY) + ":" +
- String.format("%02d", time.get(ChronoField.MINUTE_OF_HOUR));
-
- String timestamp = "[" + dateFormat + "] ";
+ String timestamp = generateTimestamp(messageNode.getTimestamp(), ZoneId.systemDefault()) + " ";
Color timestampColour = getTimestampColour();
if (timestampColour != null)
@@ -103,4 +124,24 @@ public class TimestampPlugin extends Plugin
return isChatboxTransparent ? config.transparentTimestamp() : config.opaqueTimestamp();
}
+
+ String generateTimestamp(int timestamp, ZoneId zoneId)
+ {
+ final ZonedDateTime time = ZonedDateTime.ofInstant(
+ Instant.ofEpochSecond(timestamp), zoneId);
+
+ return formatter.format(Date.from(time.toInstant()));
+ }
+
+ private void updateFormatter()
+ {
+ try
+ {
+ formatter = new SimpleDateFormat(config.timestampFormat());
+ }
+ catch (IllegalArgumentException e)
+ {
+ formatter = new SimpleDateFormat("[HH:mm]");
+ }
+ }
}
\ No newline at end of file
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/timestamp/TimestampPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/timestamp/TimestampPluginTest.java
new file mode 100644
index 0000000000..e9033043cf
--- /dev/null
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/timestamp/TimestampPluginTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019, Trevor
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.runelite.client.plugins.timestamp;
+
+import com.google.inject.Guice;
+import com.google.inject.testing.fieldbinder.Bind;
+import com.google.inject.testing.fieldbinder.BoundFieldModule;
+import java.util.TimeZone;
+import javax.inject.Inject;
+import net.runelite.api.Client;
+import net.runelite.api.events.ConfigChanged;
+import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import static org.mockito.Mockito.when;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TimestampPluginTest
+{
+ @Mock
+ @Bind
+ Client client;
+
+ @Mock
+ @Bind
+ TimestampConfig config;
+
+ @Inject
+ TimestampPlugin plugin;
+
+ @Before
+ public void before()
+ {
+ Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
+ }
+
+ @Test
+ public void testGenerateTimestamp()
+ {
+ when(config.timestampFormat()).thenReturn("[yyyy:MM:dd:HH:hh:mm:ss]");
+
+ ConfigChanged configChanged = new ConfigChanged();
+ configChanged.setGroup("timestamp");
+ configChanged.setKey("format");
+ configChanged.setNewValue("true");
+ plugin.onConfigChanged(configChanged);
+
+ int testInput = 1554667116;
+ String testOutput = "[2019:04:07:15:03:58:36]";
+ TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
+ plugin.getFormatter().setTimeZone(timeZone);
+ assertTrue(plugin.generateTimestamp(testInput, timeZone.toZoneId()).equals(testOutput));
+ }
+}