From 917726fecc2206321bd41264a66a9a39a2103d57 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 7 Mar 2020 11:23:31 +0900
Subject: [PATCH] wip #6140

---
 src/prelude/time.ts                           | 12 ++--
 .../api/endpoints/charts/active-users.ts      |  6 +-
 src/server/api/endpoints/charts/drive.ts      |  6 +-
 src/server/api/endpoints/charts/federation.ts |  6 +-
 src/server/api/endpoints/charts/hashtag.ts    |  6 +-
 src/server/api/endpoints/charts/instance.ts   |  6 +-
 src/server/api/endpoints/charts/network.ts    |  6 +-
 src/server/api/endpoints/charts/notes.ts      |  6 +-
 src/server/api/endpoints/charts/user/drive.ts |  6 +-
 .../api/endpoints/charts/user/following.ts    |  6 +-
 src/server/api/endpoints/charts/user/notes.ts |  6 +-
 .../api/endpoints/charts/user/reactions.ts    |  6 +-
 src/server/api/endpoints/charts/users.ts      |  6 +-
 src/server/api/endpoints/stats.ts             |  6 +-
 src/services/chart/core.ts                    | 47 ++++++--------
 test/chart.ts                                 | 64 +++++++++----------
 16 files changed, 96 insertions(+), 105 deletions(-)

diff --git a/src/prelude/time.ts b/src/prelude/time.ts
index 77a5fc1af2..a65366d74a 100644
--- a/src/prelude/time.ts
+++ b/src/prelude/time.ts
@@ -1,13 +1,11 @@
 const dateTimeIntervals = {
 	'day': 86400000,
 	'hour': 3600000,
+	'ms': 1,
 };
 
-export function DateUTC(time: number[]): Date {
-	const r = new Date(0);
-	r.setUTCFullYear(time[0], time[1], time[2]);
-	if (time[3]) r.setUTCHours(time[3], ...time.slice(4));
-	return r;
+export function dateUTC(time: number[]): Date {
+	return new Date(Date.UTC(...time));
 }
 
 export function isTimeSame(a: Date, b: Date): boolean {
@@ -22,10 +20,10 @@ export function isTimeAfter(a: Date, b: Date): boolean {
 	return (a.getTime() - b.getTime()) > 0;
 }
 
-export function addTimespan(x: Date, value: number, span: keyof typeof dateTimeIntervals): Date {
+export function addTime(x: Date, value: number, span: keyof typeof dateTimeIntervals = 'ms'): Date {
 	return new Date(x.getTime() + (value * dateTimeIntervals[span]));
 }
 
-export function subtractTimespan(x: Date, value: number, span: keyof typeof dateTimeIntervals): Date {
+export function subtractTime(x: Date, value: number, span: keyof typeof dateTimeIntervals = 'ms'): Date {
 	return new Date(x.getTime() - (value * dateTimeIntervals[span]));
 }
diff --git a/src/server/api/endpoints/charts/active-users.ts b/src/server/api/endpoints/charts/active-users.ts
index 327dd4de3e..df427ff4b7 100644
--- a/src/server/api/endpoints/charts/active-users.ts
+++ b/src/server/api/endpoints/charts/active-users.ts
@@ -27,8 +27,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 	},
 
@@ -36,5 +36,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await activeUsersChart.getChart(ps.span as any, ps.limit!, ps.offset!);
+	return await activeUsersChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null);
 });
diff --git a/src/server/api/endpoints/charts/drive.ts b/src/server/api/endpoints/charts/drive.ts
index 752cb6f037..e1f279fa0a 100644
--- a/src/server/api/endpoints/charts/drive.ts
+++ b/src/server/api/endpoints/charts/drive.ts
@@ -27,8 +27,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 	},
 
@@ -36,5 +36,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await driveChart.getChart(ps.span as any, ps.limit!, ps.offset!);
+	return await driveChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null);
 });
diff --git a/src/server/api/endpoints/charts/federation.ts b/src/server/api/endpoints/charts/federation.ts
index 1701f9bde4..581e42f307 100644
--- a/src/server/api/endpoints/charts/federation.ts
+++ b/src/server/api/endpoints/charts/federation.ts
@@ -27,8 +27,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 	},
 
@@ -36,5 +36,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await federationChart.getChart(ps.span as any, ps.limit!, ps.offset!);
+	return await federationChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null);
 });
diff --git a/src/server/api/endpoints/charts/hashtag.ts b/src/server/api/endpoints/charts/hashtag.ts
index bb353e7038..1aa5c86b35 100644
--- a/src/server/api/endpoints/charts/hashtag.ts
+++ b/src/server/api/endpoints/charts/hashtag.ts
@@ -27,8 +27,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 
 		tag: {
@@ -43,5 +43,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await hashtagChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.tag);
+	return await hashtagChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.tag);
 });
diff --git a/src/server/api/endpoints/charts/instance.ts b/src/server/api/endpoints/charts/instance.ts
index 3ccb2ba126..f0f85ed71a 100644
--- a/src/server/api/endpoints/charts/instance.ts
+++ b/src/server/api/endpoints/charts/instance.ts
@@ -27,8 +27,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 
 		host: {
@@ -44,5 +44,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await instanceChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.host);
+	return await instanceChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.host);
 });
diff --git a/src/server/api/endpoints/charts/network.ts b/src/server/api/endpoints/charts/network.ts
index 20f5977baa..d1337681a9 100644
--- a/src/server/api/endpoints/charts/network.ts
+++ b/src/server/api/endpoints/charts/network.ts
@@ -27,8 +27,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 	},
 
@@ -36,5 +36,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await networkChart.getChart(ps.span as any, ps.limit!, ps.offset!);
+	return await networkChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null);
 });
diff --git a/src/server/api/endpoints/charts/notes.ts b/src/server/api/endpoints/charts/notes.ts
index 5111e299e2..74aa48b36e 100644
--- a/src/server/api/endpoints/charts/notes.ts
+++ b/src/server/api/endpoints/charts/notes.ts
@@ -27,8 +27,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 	},
 
@@ -36,5 +36,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await notesChart.getChart(ps.span as any, ps.limit!, ps.offset!);
+	return await notesChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null);
 });
diff --git a/src/server/api/endpoints/charts/user/drive.ts b/src/server/api/endpoints/charts/user/drive.ts
index 576bc7be6a..5aae5bd757 100644
--- a/src/server/api/endpoints/charts/user/drive.ts
+++ b/src/server/api/endpoints/charts/user/drive.ts
@@ -28,8 +28,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 
 		userId: {
@@ -45,5 +45,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await perUserDriveChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId);
+	return await perUserDriveChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.userId);
 });
diff --git a/src/server/api/endpoints/charts/user/following.ts b/src/server/api/endpoints/charts/user/following.ts
index dcdf15b410..9d772c39c9 100644
--- a/src/server/api/endpoints/charts/user/following.ts
+++ b/src/server/api/endpoints/charts/user/following.ts
@@ -28,8 +28,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 
 		userId: {
@@ -45,5 +45,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await perUserFollowingChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId);
+	return await perUserFollowingChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.userId);
 });
diff --git a/src/server/api/endpoints/charts/user/notes.ts b/src/server/api/endpoints/charts/user/notes.ts
index 65c12d6be2..8de7c0c3e4 100644
--- a/src/server/api/endpoints/charts/user/notes.ts
+++ b/src/server/api/endpoints/charts/user/notes.ts
@@ -28,8 +28,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 
 		userId: {
@@ -45,5 +45,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await perUserNotesChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId);
+	return await perUserNotesChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.userId);
 });
diff --git a/src/server/api/endpoints/charts/user/reactions.ts b/src/server/api/endpoints/charts/user/reactions.ts
index c83a203b9c..4c37305fc3 100644
--- a/src/server/api/endpoints/charts/user/reactions.ts
+++ b/src/server/api/endpoints/charts/user/reactions.ts
@@ -28,8 +28,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 
 		userId: {
@@ -45,5 +45,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await perUserReactionsChart.getChart(ps.span as any, ps.limit!, ps.offset!, ps.userId);
+	return await perUserReactionsChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null, ps.userId);
 });
diff --git a/src/server/api/endpoints/charts/users.ts b/src/server/api/endpoints/charts/users.ts
index 7f52184f16..18eec384a6 100644
--- a/src/server/api/endpoints/charts/users.ts
+++ b/src/server/api/endpoints/charts/users.ts
@@ -27,8 +27,8 @@ export const meta = {
 		},
 
 		offset: {
-			validator: $.optional.num,
-			default: 0,
+			validator: $.optional.nullable.num,
+			default: null,
 		},
 	},
 
@@ -36,5 +36,5 @@ export const meta = {
 };
 
 export default define(meta, async (ps) => {
-	return await usersChart.getChart(ps.span as any, ps.limit!, ps.offset!);
+	return await usersChart.getChart(ps.span as any, ps.limit!, ps.offset ? new Date(ps.offset) : null);
 });
diff --git a/src/server/api/endpoints/stats.ts b/src/server/api/endpoints/stats.ts
index a6ee240a89..dab05c1675 100644
--- a/src/server/api/endpoints/stats.ts
+++ b/src/server/api/endpoints/stats.ts
@@ -60,9 +60,9 @@ export default define(meta, async () => {
 		Notes.count({ where: { userHost: null }, cache: 3600000 }),
 		Users.count({ cache: 3600000 }),
 		Users.count({ where: { host: null }, cache: 3600000 }),
-		federationChart.getChart('hour', 1, 0).then(chart => chart.instance.total[0]),
-		driveChart.getChart('hour', 1, 0).then(chart => chart.local.totalSize[0]),
-		driveChart.getChart('hour', 1, 0).then(chart => chart.remote.totalSize[0]),
+		federationChart.getChart('hour', 1, null).then(chart => chart.instance.total[0]),
+		driveChart.getChart('hour', 1, null).then(chart => chart.local.totalSize[0]),
+		driveChart.getChart('hour', 1, null).then(chart => chart.remote.totalSize[0]),
 	]);
 
 	return {
diff --git a/src/services/chart/core.ts b/src/services/chart/core.ts
index ca24082e73..dc09923ae4 100644
--- a/src/services/chart/core.ts
+++ b/src/services/chart/core.ts
@@ -8,8 +8,8 @@ import * as nestedProperty from 'nested-property';
 import autobind from 'autobind-decorator';
 import Logger from '../logger';
 import { Schema } from '../../misc/schema';
-import { EntitySchema, getRepository, Repository, LessThan, MoreThanOrEqual, Between } from 'typeorm';
-import { DateUTC, isTimeSame, isTimeBefore, subtractTimespan } from '../../prelude/time';
+import { EntitySchema, getRepository, Repository, LessThan, Between } from 'typeorm';
+import { dateUTC, isTimeSame, isTimeBefore, subtractTime, addTime } from '../../prelude/time';
 import { getChartInsertLock } from '../../misc/app-lock';
 
 const logger = new Logger('chart', 'white', process.env.NODE_ENV !== 'test');
@@ -134,18 +134,21 @@ export default abstract class Chart<T extends Record<string, any>> {
 	}
 
 	@autobind
-	private static dateToYMDH(date: Date): [number, number, number, number] {
+	private static parseDate(date: Date): [number, number, number, number, number, number, number] {
 		const y = date.getUTCFullYear();
 		const m = date.getUTCMonth();
 		const d = date.getUTCDate();
 		const h = date.getUTCHours();
+		const _m = date.getUTCMinutes();
+		const _s = date.getUTCSeconds();
+		const _ms = date.getUTCMilliseconds();
 
-		return [y, m, d, h];
+		return [y, m, d, h, _m, _s, _ms];
 	}
 
 	@autobind
-	private static getCurrentDate(): [number, number, number, number] {
-		return Chart.dateToYMDH(new Date());
+	private static getCurrentDate() {
+		return Chart.parseDate(new Date());
 	}
 
 	@autobind
@@ -243,8 +246,8 @@ export default abstract class Chart<T extends Record<string, any>> {
 		const [y, m, d, h] = Chart.getCurrentDate();
 
 		const current =
-			span == 'day' ? DateUTC([y, m, d]) :
-			span == 'hour' ? DateUTC([y, m, d, h]) :
+			span == 'day' ? dateUTC([y, m, d, 0]) :
+			span == 'hour' ? dateUTC([y, m, d, h]) :
 			null as never;
 
 		// 現在(今日または今のHour)のログ
@@ -381,23 +384,15 @@ export default abstract class Chart<T extends Record<string, any>> {
 	}
 
 	@autobind
-	public async getChart(span: Span, amount: number, offset: number, group: string | null = null): Promise<ArrayValue<T>> {
-		let [y, m, d, h] = Chart.getCurrentDate();
+	public async getChart(span: Span, amount: number, begin: Date | null, group: string | null = null): Promise<ArrayValue<T>> {
+		const [y, m, d, h, _m, _s, _ms] = begin ? Chart.parseDate(subtractTime(addTime(begin, 1, span), 1)) : Chart.getCurrentDate();
+		const [y2, m2, d2, h2] = begin ? Chart.parseDate(addTime(begin, 1, span)) : [] as never;
 
-		let lt: Date = null as never;
-
-		if (offset > 0) {
-			[y, m, d, h] = Chart.dateToYMDH(subtractTimespan(DateUTC([y, m, d, h]), offset, span));
-
-			lt =
-				span === 'day' ? DateUTC([y, m, d]) :
-				span === 'hour' ? DateUTC([y, m, d, h]) :
-				null as never;
-		}
+		const lt = dateUTC([y, m, d, h, _m, _s, _ms]);
 
 		const gt =
-			span === 'day' ? subtractTimespan(DateUTC([y, m, d]), amount - 1, 'day') :
-			span === 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), amount - 1, 'hour') :
+			span === 'day' ? subtractTime(begin ? dateUTC([y2, m2, d2, 0]) : dateUTC([y, m, d, 0]), amount - 1, 'day') :
+			span === 'hour' ? subtractTime(begin ? dateUTC([y2, m2, d2, h2]) : dateUTC([y, m, d, h]), amount - 1, 'hour') :
 			null as never;
 
 		// ログ取得
@@ -405,9 +400,7 @@ export default abstract class Chart<T extends Record<string, any>> {
 			where: {
 				group: group,
 				span: span,
-				date: offset === 0
-					? MoreThanOrEqual(Chart.dateToTimestamp(gt))
-					: Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt))
+				date: Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt))
 			},
 			order: {
 				date: -1
@@ -455,8 +448,8 @@ export default abstract class Chart<T extends Record<string, any>> {
 		// 整形
 		for (let i = (amount - 1); i >= 0; i--) {
 			const current =
-				span == 'day' ? subtractTimespan(DateUTC([y, m, d]), i, 'day') :
-				span == 'hour' ? subtractTimespan(DateUTC([y, m, d, h]), i, 'hour') :
+				span === 'day' ? subtractTime(dateUTC([y, m, d, 0]), i, 'day') :
+				span === 'hour' ? subtractTime(dateUTC([y, m, d, h]), i, 'hour') :
 				null as never;
 
 			const log = logs.find(l => isTimeSame(new Date(l.date * 1000), current));
diff --git a/test/chart.ts b/test/chart.ts
index 6a04569a90..5548d1869f 100644
--- a/test/chart.ts
+++ b/test/chart.ts
@@ -86,8 +86,8 @@ describe('Chart', () => {
 	it('Can updates', async(async () => {
 		await testChart.increment();
 
-		const chartHours = await testChart.getChart('hour', 3, 0);
-		const chartDays = await testChart.getChart('day', 3, 0);
+		const chartHours = await testChart.getChart('hour', 3, null);
+		const chartDays = await testChart.getChart('day', 3, null);
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -109,8 +109,8 @@ describe('Chart', () => {
 	it('Can updates (dec)', async(async () => {
 		await testChart.decrement();
 
-		const chartHours = await testChart.getChart('hour', 3, 0);
-		const chartDays = await testChart.getChart('day', 3, 0);
+		const chartHours = await testChart.getChart('hour', 3, null);
+		const chartDays = await testChart.getChart('day', 3, null);
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -130,8 +130,8 @@ describe('Chart', () => {
 	}));
 
 	it('Empty chart', async(async () => {
-		const chartHours = await testChart.getChart('hour', 3, 0);
-		const chartDays = await testChart.getChart('day', 3, 0);
+		const chartHours = await testChart.getChart('hour', 3, null);
+		const chartDays = await testChart.getChart('day', 3, null);
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -155,8 +155,8 @@ describe('Chart', () => {
 		await testChart.increment();
 		await testChart.increment();
 
-		const chartHours = await testChart.getChart('hour', 3, 0);
-		const chartDays = await testChart.getChart('day', 3, 0);
+		const chartHours = await testChart.getChart('hour', 3, null);
+		const chartDays = await testChart.getChart('day', 3, null);
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -182,8 +182,8 @@ describe('Chart', () => {
 
 		await testChart.increment();
 
-		const chartHours = await testChart.getChart('hour', 3, 0);
-		const chartDays = await testChart.getChart('day', 3, 0);
+		const chartHours = await testChart.getChart('hour', 3, null);
+		const chartDays = await testChart.getChart('day', 3, null);
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -209,8 +209,8 @@ describe('Chart', () => {
 
 		await testChart.increment();
 
-		const chartHours = await testChart.getChart('hour', 3, 0);
-		const chartDays = await testChart.getChart('day', 3, 0);
+		const chartHours = await testChart.getChart('hour', 3, null);
+		const chartDays = await testChart.getChart('day', 3, null);
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -235,8 +235,8 @@ describe('Chart', () => {
 
 		clock.tick('05:00:00');
 
-		const chartHours = await testChart.getChart('hour', 3, 0);
-		const chartDays = await testChart.getChart('day', 3, 0);
+		const chartHours = await testChart.getChart('hour', 3, null);
+		const chartDays = await testChart.getChart('day', 3, null);
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -262,8 +262,8 @@ describe('Chart', () => {
 		clock.tick('05:00:00');
 		await testChart.increment();
 
-		const chartHours = await testChart.getChart('hour', 3, 0);
-		const chartDays = await testChart.getChart('day', 3, 0);
+		const chartHours = await testChart.getChart('hour', 3, null);
+		const chartDays = await testChart.getChart('day', 3, null);
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -289,8 +289,8 @@ describe('Chart', () => {
 
 		await testChart.increment();
 
-		const chartHours = await testChart.getChart('hour', 3, 1);
-		const chartDays = await testChart.getChart('day', 3, 1);
+		const chartHours = await testChart.getChart('hour', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0)));
+		const chartDays = await testChart.getChart('day', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0)));
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -303,8 +303,8 @@ describe('Chart', () => {
 		assert.deepStrictEqual(chartDays, {
 			foo: {
 				dec: [0, 0, 0],
-				inc: [0, 0, 0],
-				total: [0, 0, 0]
+				inc: [2, 0, 0],
+				total: [2, 0, 0]
 			},
 		});
 	}));
@@ -318,8 +318,8 @@ describe('Chart', () => {
 
 		await testChart.increment();
 
-		const chartHours = await testChart.getChart('hour', 3, 1);
-		const chartDays = await testChart.getChart('day', 3, 1);
+		const chartHours = await testChart.getChart('hour', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0)));
+		const chartDays = await testChart.getChart('day', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0)));
 
 		assert.deepStrictEqual(chartHours, {
 			foo: {
@@ -342,10 +342,10 @@ describe('Chart', () => {
 		it('Can updates', async(async () => {
 			await testGroupedChart.increment('alice');
 
-			const aliceChartHours = await testGroupedChart.getChart('hour', 3, 0, 'alice');
-			const aliceChartDays = await testGroupedChart.getChart('day', 3, 0, 'alice');
-			const bobChartHours = await testGroupedChart.getChart('hour', 3, 0, 'bob');
-			const bobChartDays = await testGroupedChart.getChart('day', 3, 0, 'bob');
+			const aliceChartHours = await testGroupedChart.getChart('hour', 3, null, 'alice');
+			const aliceChartDays = await testGroupedChart.getChart('day', 3, null, 'alice');
+			const bobChartHours = await testGroupedChart.getChart('hour', 3, null, 'bob');
+			const bobChartDays = await testGroupedChart.getChart('day', 3, null, 'bob');
 
 			assert.deepStrictEqual(aliceChartHours, {
 				foo: {
@@ -387,8 +387,8 @@ describe('Chart', () => {
 			await testUniqueChart.uniqueIncrement('alice');
 			await testUniqueChart.uniqueIncrement('bob');
 
-			const chartHours = await testUniqueChart.getChart('hour', 3, 0);
-			const chartDays = await testUniqueChart.getChart('day', 3, 0);
+			const chartHours = await testUniqueChart.getChart('hour', 3, null);
+			const chartDays = await testUniqueChart.getChart('day', 3, null);
 
 			assert.deepStrictEqual(chartHours, {
 				foo: [2, 0, 0],
@@ -406,8 +406,8 @@ describe('Chart', () => {
 
 			await testChart.resync();
 
-			const chartHours = await testChart.getChart('hour', 3, 0);
-			const chartDays = await testChart.getChart('day', 3, 0);
+			const chartHours = await testChart.getChart('hour', 3, null);
+			const chartDays = await testChart.getChart('day', 3, null);
 
 			assert.deepStrictEqual(chartHours, {
 				foo: {
@@ -435,8 +435,8 @@ describe('Chart', () => {
 
 			await testChart.resync();
 
-			const chartHours = await testChart.getChart('hour', 3, 0);
-			const chartDays = await testChart.getChart('day', 3, 0);
+			const chartHours = await testChart.getChart('hour', 3, null);
+			const chartDays = await testChart.getChart('day', 3, null);
 
 			assert.deepStrictEqual(chartHours, {
 				foo: {