mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-01-08 17:37:34 +01:00
Fixed timezone offset trouble:
- Day by Day graph no longer applies timezone offset twice - MySQL no longer applies timezone offset on its own (Connections set timezone to UTC) - Server calendar possibly fixed
This commit is contained in:
parent
68a2c3b571
commit
2139067ac5
@ -119,14 +119,12 @@ public class GraphJSONParser {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return "{\"uniquePlayers\":" +
|
return "{\"uniquePlayers\":" +
|
||||||
lineGraphs.lineGraph(MutatorFunctions.toPointsWithRemovedOffset(
|
lineGraphs.lineGraph(MutatorFunctions.toPoints(
|
||||||
MutatorFunctions.addMissing(uniquePerDay, TimeUnit.DAYS.toMillis(1L), 0),
|
MutatorFunctions.addMissing(uniquePerDay, TimeUnit.DAYS.toMillis(1L), 0)
|
||||||
timeZone
|
|
||||||
)).toHighChartsSeries() +
|
)).toHighChartsSeries() +
|
||||||
",\"newPlayers\":" +
|
",\"newPlayers\":" +
|
||||||
lineGraphs.lineGraph(MutatorFunctions.toPointsWithRemovedOffset(
|
lineGraphs.lineGraph(MutatorFunctions.toPoints(
|
||||||
MutatorFunctions.addMissing(newPerDay, TimeUnit.DAYS.toMillis(1L), 0),
|
MutatorFunctions.addMissing(newPerDay, TimeUnit.DAYS.toMillis(1L), 0)
|
||||||
timeZone
|
|
||||||
)).toHighChartsSeries() +
|
)).toHighChartsSeries() +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
@ -144,14 +142,12 @@ public class GraphJSONParser {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return "{\"uniquePlayers\":" +
|
return "{\"uniquePlayers\":" +
|
||||||
lineGraphs.lineGraph(MutatorFunctions.toPointsWithRemovedOffset(
|
lineGraphs.lineGraph(MutatorFunctions.toPoints(
|
||||||
MutatorFunctions.addMissing(uniquePerDay, TimeUnit.DAYS.toMillis(1L), 0),
|
MutatorFunctions.addMissing(uniquePerDay, TimeUnit.DAYS.toMillis(1L), 0)
|
||||||
timeZone
|
|
||||||
)).toHighChartsSeries() +
|
)).toHighChartsSeries() +
|
||||||
",\"newPlayers\":" +
|
",\"newPlayers\":" +
|
||||||
lineGraphs.lineGraph(MutatorFunctions.toPointsWithRemovedOffset(
|
lineGraphs.lineGraph(MutatorFunctions.toPoints(
|
||||||
MutatorFunctions.addMissing(newPerDay, TimeUnit.DAYS.toMillis(1L), 0),
|
MutatorFunctions.addMissing(newPerDay, TimeUnit.DAYS.toMillis(1L), 0)
|
||||||
timeZone
|
|
||||||
)).toHighChartsSeries() +
|
)).toHighChartsSeries() +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,7 @@ public class CalendarFactory {
|
|||||||
) {
|
) {
|
||||||
return new ServerCalendar(
|
return new ServerCalendar(
|
||||||
uniquePerDay, newPerDay, playtimePerDay, sessionsPerDay,
|
uniquePerDay, newPerDay, playtimePerDay, sessionsPerDay,
|
||||||
formatters.iso8601NoClockLong(), formatters.timeAmount(), theme, locale,
|
formatters.iso8601NoClockLong(), formatters.timeAmount(), theme, locale
|
||||||
config.getTimeZone()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,7 +25,6 @@ import com.djrapitops.plan.settings.theme.ThemeVal;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NavigableMap;
|
import java.util.NavigableMap;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility for creating FullCalendar calendar event array on Player page.
|
* Utility for creating FullCalendar calendar event array on Player page.
|
||||||
@ -43,7 +42,6 @@ public class ServerCalendar {
|
|||||||
private final Formatter<Long> timeAmountFormatter;
|
private final Formatter<Long> timeAmountFormatter;
|
||||||
private final Theme theme;
|
private final Theme theme;
|
||||||
private final Locale locale;
|
private final Locale locale;
|
||||||
private final TimeZone timeZone;
|
|
||||||
|
|
||||||
ServerCalendar(
|
ServerCalendar(
|
||||||
SortedMap<Long, Integer> uniquePerDay,
|
SortedMap<Long, Integer> uniquePerDay,
|
||||||
@ -53,8 +51,7 @@ public class ServerCalendar {
|
|||||||
Formatter<Long> iso8601Formatter,
|
Formatter<Long> iso8601Formatter,
|
||||||
Formatter<Long> timeAmountFormatter,
|
Formatter<Long> timeAmountFormatter,
|
||||||
Theme theme,
|
Theme theme,
|
||||||
Locale locale,
|
Locale locale
|
||||||
TimeZone timeZone
|
|
||||||
) {
|
) {
|
||||||
this.uniquePerDay = uniquePerDay;
|
this.uniquePerDay = uniquePerDay;
|
||||||
this.newPerDay = newPerDay;
|
this.newPerDay = newPerDay;
|
||||||
@ -64,7 +61,6 @@ public class ServerCalendar {
|
|||||||
this.playtimePerDay = playtimePerDay;
|
this.playtimePerDay = playtimePerDay;
|
||||||
this.theme = theme;
|
this.theme = theme;
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.timeZone = timeZone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toCalendarSeries() {
|
public String toCalendarSeries() {
|
||||||
@ -77,7 +73,6 @@ public class ServerCalendar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void appendTimeZoneOffsetData(StringBuilder series) {
|
private void appendTimeZoneOffsetData(StringBuilder series) {
|
||||||
// Has a timezone offset
|
|
||||||
appendUniquePlayers(series);
|
appendUniquePlayers(series);
|
||||||
appendNewPlayers(series);
|
appendNewPlayers(series);
|
||||||
appendSessionCounts(series);
|
appendSessionCounts(series);
|
||||||
@ -92,7 +87,7 @@ public class ServerCalendar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Long key = entry.getKey();
|
Long key = entry.getKey();
|
||||||
String day = iso8601Formatter.apply(key - timeZone.getOffset(key));// Remove the timezone offset since Calendar uses UTC
|
String day = iso8601Formatter.apply(key);
|
||||||
|
|
||||||
series.append(",{\"title\": \"").append(locale.get(HtmlLang.NEW_CALENDAR)).append(" ").append(newPlayers)
|
series.append(",{\"title\": \"").append(locale.get(HtmlLang.NEW_CALENDAR)).append(" ").append(newPlayers)
|
||||||
.append("\",\"start\":\"").append(day)
|
.append("\",\"start\":\"").append(day)
|
||||||
@ -109,7 +104,7 @@ public class ServerCalendar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Long key = entry.getKey();
|
Long key = entry.getKey();
|
||||||
String day = iso8601Formatter.apply(key - timeZone.getOffset(key));// Remove the timezone offset since Calendar uses UTC
|
String day = iso8601Formatter.apply(key);
|
||||||
|
|
||||||
series.append(",{\"title\": \"").append(locale.get(HtmlLang.UNIQUE_CALENDAR)).append(" ").append(uniquePlayers)
|
series.append(",{\"title\": \"").append(locale.get(HtmlLang.UNIQUE_CALENDAR)).append(" ").append(uniquePlayers)
|
||||||
.append("\",\"start\":\"").append(day)
|
.append("\",\"start\":\"").append(day)
|
||||||
@ -125,7 +120,7 @@ public class ServerCalendar {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Long key = entry.getKey();
|
Long key = entry.getKey();
|
||||||
String day = iso8601Formatter.apply(key - timeZone.getOffset(key));// Remove the timezone offset since Calendar uses UTC
|
String day = iso8601Formatter.apply(key);
|
||||||
|
|
||||||
series.append(",{\"title\": \"").append(locale.get(HtmlLang.LABEL_PLAYTIME)).append(": ").append(timeAmountFormatter.apply(playtime))
|
series.append(",{\"title\": \"").append(locale.get(HtmlLang.LABEL_PLAYTIME)).append(": ").append(timeAmountFormatter.apply(playtime))
|
||||||
.append("\",\"start\":\"").append(day)
|
.append("\",\"start\":\"").append(day)
|
||||||
@ -141,7 +136,7 @@ public class ServerCalendar {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Long key = entry.getKey();
|
Long key = entry.getKey();
|
||||||
String day = iso8601Formatter.apply(key - timeZone.getOffset(key));// Remove the timezone offset since Calendar uses UTC
|
String day = iso8601Formatter.apply(key);
|
||||||
|
|
||||||
series.append(",{\"title\": \"").append(locale.get(HtmlLang.SIDE_SESSIONS)).append(": ").append(sessionCount)
|
series.append(",{\"title\": \"").append(locale.get(HtmlLang.SIDE_SESSIONS)).append(": ").append(sessionCount)
|
||||||
.append("\",\"start\":\"").append(day)
|
.append("\",\"start\":\"").append(day)
|
||||||
|
@ -39,6 +39,7 @@ import javax.inject.Singleton;
|
|||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -140,9 +141,16 @@ public class MySQLDB extends SQLDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (connection.getAutoCommit()) connection.setAutoCommit(false);
|
if (connection.getAutoCommit()) connection.setAutoCommit(false);
|
||||||
|
setTimezoneToUTC(connection);
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setTimezoneToUTC(Connection connection) throws SQLException {
|
||||||
|
try (Statement statement = connection.createStatement()) {
|
||||||
|
statement.execute("set time_zone = '+00:00'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
super.close();
|
super.close();
|
||||||
|
@ -130,7 +130,7 @@ public class PlayerCountQueries {
|
|||||||
* @param before Before epoch ms
|
* @param before Before epoch ms
|
||||||
* @param timeZoneOffset Offset from {@link java.util.TimeZone#getOffset(long)}, applied to the dates before grouping.
|
* @param timeZoneOffset Offset from {@link java.util.TimeZone#getOffset(long)}, applied to the dates before grouping.
|
||||||
* @param serverUUID UUID of the Plan server
|
* @param serverUUID UUID of the Plan server
|
||||||
* @return Map: Epoch ms (Accuracy of a day) - How many unique players played that day
|
* @return Map: Epoch ms (Start of day at 0 AM, no offset) - How many unique players played that day
|
||||||
*/
|
*/
|
||||||
public static Query<NavigableMap<Long, Integer>> uniquePlayerCounts(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
public static Query<NavigableMap<Long, Integer>> uniquePlayerCounts(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
return database -> {
|
return database -> {
|
||||||
@ -172,7 +172,7 @@ public class PlayerCountQueries {
|
|||||||
* @param after After epoch ms
|
* @param after After epoch ms
|
||||||
* @param before Before epoch ms
|
* @param before Before epoch ms
|
||||||
* @param timeZoneOffset Offset from {@link java.util.TimeZone#getOffset(long)}, applied to the dates before grouping.
|
* @param timeZoneOffset Offset from {@link java.util.TimeZone#getOffset(long)}, applied to the dates before grouping.
|
||||||
* @return Map: Epoch ms (Accuracy of a day) - How many unique players played that day
|
* @return Map: Epoch ms (Start of day at 0 AM, no offset) - How many unique players played that day
|
||||||
*/
|
*/
|
||||||
public static Query<NavigableMap<Long, Integer>> uniquePlayerCounts(long after, long before, long timeZoneOffset) {
|
public static Query<NavigableMap<Long, Integer>> uniquePlayerCounts(long after, long before, long timeZoneOffset) {
|
||||||
return database -> {
|
return database -> {
|
||||||
@ -288,7 +288,7 @@ public class PlayerCountQueries {
|
|||||||
* @param before Before epoch ms
|
* @param before Before epoch ms
|
||||||
* @param timeZoneOffset Offset from {@link java.util.TimeZone#getOffset(long)}, applied to the dates before grouping.
|
* @param timeZoneOffset Offset from {@link java.util.TimeZone#getOffset(long)}, applied to the dates before grouping.
|
||||||
* @param serverUUID UUID of the Plan server
|
* @param serverUUID UUID of the Plan server
|
||||||
* @return Map: Epoch ms (Accuracy of a day) - How many new players joined that day
|
* @return Map: Epoch ms (Start of day at 0 AM, no offset) - How many new players joined that day
|
||||||
*/
|
*/
|
||||||
public static Query<NavigableMap<Long, Integer>> newPlayerCounts(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
public static Query<NavigableMap<Long, Integer>> newPlayerCounts(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
return database -> {
|
return database -> {
|
||||||
@ -324,6 +324,14 @@ public class PlayerCountQueries {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a EpochMs - Count map of new players on a server.
|
||||||
|
*
|
||||||
|
* @param after After epoch ms
|
||||||
|
* @param before Before epoch ms
|
||||||
|
* @param timeZoneOffset Offset from {@link java.util.TimeZone#getOffset(long)}, applied to the dates before grouping.
|
||||||
|
* @return Map: Epoch ms (Start of day at 0 AM, no offset) - How many new players joined that day
|
||||||
|
*/
|
||||||
public static Query<NavigableMap<Long, Integer>> newPlayerCounts(long after, long before, long timeZoneOffset) {
|
public static Query<NavigableMap<Long, Integer>> newPlayerCounts(long after, long before, long timeZoneOffset) {
|
||||||
return database -> {
|
return database -> {
|
||||||
Sql sql = database.getSql();
|
Sql sql = database.getSql();
|
||||||
|
@ -439,6 +439,15 @@ public class SessionQueries {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query session count for each day within range on a server.
|
||||||
|
*
|
||||||
|
* @param after After epoch ms
|
||||||
|
* @param before Before epoch ms
|
||||||
|
* @param timeZoneOffset Offset in ms to determine start of day.
|
||||||
|
* @param serverUUID UUID of the Plan server.
|
||||||
|
* @return Map - Epoch ms (Start of day at 0 AM, no offset) : Session count of that day
|
||||||
|
*/
|
||||||
public static Query<NavigableMap<Long, Integer>> sessionCountPerDay(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
public static Query<NavigableMap<Long, Integer>> sessionCountPerDay(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
return database -> {
|
return database -> {
|
||||||
Sql sql = database.getSql();
|
Sql sql = database.getSql();
|
||||||
@ -539,6 +548,15 @@ public class SessionQueries {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query playtime for each day within range on a server.
|
||||||
|
*
|
||||||
|
* @param after After epoch ms
|
||||||
|
* @param before Before epoch ms
|
||||||
|
* @param timeZoneOffset Offset in ms to determine start of day.
|
||||||
|
* @param serverUUID UUID of the Plan server.
|
||||||
|
* @return Map - Epoch ms (Start of day at 0 AM, no offset) : Playtime of that day
|
||||||
|
*/
|
||||||
public static Query<NavigableMap<Long, Long>> playtimePerDay(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
public static Query<NavigableMap<Long, Long>> playtimePerDay(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
return database -> {
|
return database -> {
|
||||||
Sql sql = database.getSql();
|
Sql sql = database.getSql();
|
||||||
|
@ -130,6 +130,25 @@ function lineChart(id, series) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dayByDay(id, series) {
|
||||||
|
graphs.push(Highcharts.stockChart(id, {
|
||||||
|
rangeSelector: {
|
||||||
|
selected: 2,
|
||||||
|
buttons: linegraphButtons
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
softMax: 2,
|
||||||
|
softMin: 0
|
||||||
|
},
|
||||||
|
title: {text: ''},
|
||||||
|
legend: {
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
time: {timezoneOffset: 0},
|
||||||
|
series: series
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
function onlineActivityCalendar(id, events, firstDay) {
|
function onlineActivityCalendar(id, events, firstDay) {
|
||||||
$(id).fullCalendar({
|
$(id).fullCalendar({
|
||||||
eventColor: '#2196F3',
|
eventColor: '#2196F3',
|
||||||
|
@ -891,7 +891,7 @@
|
|||||||
name: s.name.newPlayers, type: s.type.spline, tooltip: s.tooltip.zeroDecimals,
|
name: s.name.newPlayers, type: s.type.spline, tooltip: s.tooltip.zeroDecimals,
|
||||||
data: data.newPlayers, color: v.colors.newPlayers
|
data: data.newPlayers, color: v.colors.newPlayers
|
||||||
};
|
};
|
||||||
lineChart('uniqueChart', [uniquePlayers, newPlayers]);
|
dayByDay('uniqueChart', [uniquePlayers, newPlayers]);
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
$('#uniqueChart').text("Failed to load graph data: " + error)
|
$('#uniqueChart').text("Failed to load graph data: " + error)
|
||||||
}
|
}
|
||||||
|
@ -1547,7 +1547,7 @@
|
|||||||
name: s.name.newPlayers, type: s.type.spline, tooltip: s.tooltip.zeroDecimals,
|
name: s.name.newPlayers, type: s.type.spline, tooltip: s.tooltip.zeroDecimals,
|
||||||
data: data.newPlayers, color: v.colors.newPlayers
|
data: data.newPlayers, color: v.colors.newPlayers
|
||||||
};
|
};
|
||||||
lineChart('uniqueChart', [uniquePlayers, newPlayers]);
|
dayByDay('uniqueChart', [uniquePlayers, newPlayers]);
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
$('#uniqueChart').text("Failed to load graph data: " + error)
|
$('#uniqueChart').text("Failed to load graph data: " + error)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user