From 9c0e99056895accc3480639c22b2ef9b6b5f35f3 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Sat, 10 Nov 2018 23:25:09 +0900
Subject: [PATCH] Better chart generation

---
 package.json       |  1 +
 src/chart/index.ts | 48 ++++++++++++++++++++++++++++++----------------
 2 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/package.json b/package.json
index e62981d781..85cf5e1f6b 100644
--- a/package.json
+++ b/package.json
@@ -155,6 +155,7 @@
 		"mkdirp": "0.5.1",
 		"mocha": "5.2.0",
 		"moji": "0.5.1",
+		"moment": "2.22.2",
 		"mongodb": "3.1.8",
 		"monk": "6.0.6",
 		"ms": "2.1.1",
diff --git a/src/chart/index.ts b/src/chart/index.ts
index 4cd61de9ce..c12e659023 100644
--- a/src/chart/index.ts
+++ b/src/chart/index.ts
@@ -2,12 +2,15 @@
  * チャートエンジン
  */
 
+import * as moment from 'moment';
 const nestedProperty = require('nested-property');
 import autobind from 'autobind-decorator';
 import * as mongo from 'mongodb';
 import db from '../db/mongodb';
 import { ICollection } from 'monk';
 
+const utc = moment.utc;
+
 export type Obj = { [key: string]: any };
 
 export type Partial<T> = {
@@ -63,6 +66,19 @@ export default abstract class Chart<T> {
 		} else {
 			this.collection.createIndex({ span: -1, date: -1 }, { unique: true });
 		}
+
+		//#region 後方互換性のため
+		this.collection.find({ span: 'day' }, { fields: { _id: true, date: true } }).then(logs => {
+			logs.forEach(log => {
+				this.collection.update({ _id: log._id }, { $set: { date: utc(log.date).hour(0).toDate() } });
+			});
+		});
+		this.collection.find({ span: 'hour' }, { fields: { _id: true, date: true } }).then(logs => {
+			logs.forEach(log => {
+				this.collection.update({ _id: log._id }, { $set: { date: utc(log.date).toDate() } });
+			});
+		});
+		//#endregion
 	}
 
 	@autobind
@@ -87,12 +103,12 @@ export default abstract class Chart<T> {
 
 	@autobind
 	private getCurrentDate(): [number, number, number, number] {
-		const now = new Date();
+		const now = moment().utc();
 
-		const y = now.getFullYear();
-		const m = now.getMonth();
-		const d = now.getDate();
-		const h = now.getHours();
+		const y = now.year();
+		const m = now.month();
+		const d = now.date();
+		const h = now.hour();
 
 		return [y, m, d, h];
 	}
@@ -114,15 +130,15 @@ export default abstract class Chart<T> {
 		const [y, m, d, h] = this.getCurrentDate();
 
 		const current =
-			span == 'day' ? new Date(y, m, d) :
-			span == 'hour' ? new Date(y, m, d, h) :
+			span == 'day' ? utc([y, m, d]) :
+			span == 'hour' ? utc([y, m, d, h]) :
 			null;
 
 		// 現在(今日または今のHour)のログ
 		const currentLog = await this.collection.findOne({
 			group: group,
 			span: span,
-			date: current
+			date: current.toDate()
 		});
 
 		// ログがあればそれを返して終了
@@ -158,7 +174,7 @@ export default abstract class Chart<T> {
 			log = await this.collection.insert({
 				group: group,
 				span: span,
-				date: current,
+				date: current.toDate(),
 				data: data
 			});
 		} catch (e) {
@@ -225,8 +241,8 @@ export default abstract class Chart<T> {
 		const [y, m, d, h] = this.getCurrentDate();
 
 		const gt =
-			span == 'day' ? new Date(y, m, d - range) :
-			span == 'hour' ? new Date(y, m, d, h - range) :
+			span == 'day' ? utc([y, m, d - range]) :
+			span == 'hour' ? utc([y, m, d, h - range]) :
 			null;
 
 		// ログ取得
@@ -234,7 +250,7 @@ export default abstract class Chart<T> {
 			group: group,
 			span: span,
 			date: {
-				$gt: gt
+				$gt: gt.toDate()
 			}
 		}, {
 			sort: {
@@ -269,17 +285,17 @@ export default abstract class Chart<T> {
 		// 整形
 		for (let i = (range - 1); i >= 0; i--) {
 			const current =
-				span == 'day' ? new Date(y, m, d - i) :
-				span == 'hour' ? new Date(y, m, d, h - i) :
+				span == 'day' ? utc([y, m, d - i]) :
+				span == 'hour' ? utc([y, m, d, h - i]) :
 				null;
 
-			const log = logs.find(l => l.date.getTime() == current.getTime());
+			const log = logs.find(l => utc(l.date).isSame(current));
 
 			if (log) {
 				promisedChart.unshift(Promise.resolve(log.data));
 			} else {
 				// 隙間埋め
-				const latest = logs.find(l => l.date.getTime() < current.getTime());
+				const latest = logs.find(l => utc(l.date).isBefore(current));
 				promisedChart.unshift(this.getTemplate(false, latest ? latest.data : null));
 			}
 		}