Skip to content

Commit

Permalink
use luxon library for date & time, augment the module with workaround…
Browse files Browse the repository at this point in the history
  • Loading branch information
function2 committed May 3, 2021
1 parent 51631d6 commit b67efb1
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 24 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"description": "一个在北京时间(UTC+8)整点进行报时的 bot。A bot reports time on the hour.",
"homepage": "https://github.com/function2-llx/zhengdianbaoshi_bot",
"dependencies": {
"luxon": "1.26.0",
"mathjs": "9.3.2",
"node-telegram-bot-api": "0.53.0",
"reflect-metadata": "^0.1.13",
Expand All @@ -11,6 +12,7 @@
"winston": "3.3.3"
},
"devDependencies": {
"@types/luxon": "^1.26.5",
"@types/mathjs": "6.0.11",
"@types/node": "^15.0.1",
"@types/node-telegram-bot-api": "0.51.1",
Expand Down
24 changes: 13 additions & 11 deletions src/aug.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
import * as TelegramBot from 'node-telegram-bot-api';
// workaround for https://github.com/microsoft/TypeScript/issues/18877
import { DateTime } from 'luxon/src/datetime'

declare global {
interface Date {
declare module 'luxon/src/datetime' {
interface DateTime {
/**
* 转为日期+小时的字符串,按照当前 locale 格式
*/
toLocaleDateHoursString(): string;

/**
* 获取到下一小时的毫秒数
* @param minutes 延迟分钟数
* @param seconds 延迟秒数
*/
/**
* 获取到下一小时的毫秒数
* @param minutes 延迟分钟数
* @param seconds 延迟秒数
*/
getNextHourTimeout(minutes?: number, seconds?: number): number;
}
}

Date.prototype.toLocaleDateHoursString = function(this: Date): string {
return String([this.toLocaleDateString(), this.getHours()]);
DateTime.prototype.toLocaleDateHoursString = function (this: DateTime): string {
return String([this.toLocaleString(DateTime.DATE_SHORT), this.hour]);
}

Date.prototype.getNextHourTimeout = function(this: Date, minutes = 0, seconds = 0): number {
return ((59 - this.getMinutes() + minutes) * 60 + 59 - this.getSeconds() + seconds) * 1000 + 1000 - this.getMilliseconds();
DateTime.prototype.getNextHourTimeout = function(this: DateTime, minutes = 0, seconds = 0): number {
return ((59 - this.minute + minutes) * 60 + 59 - this.second + seconds) * 1000 + 1000 - this.millisecond;
}

// It's insane ts does not allow default interface default implementation
Expand Down
2 changes: 1 addition & 1 deletion src/entity/Group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ export class Group extends BaseEntity {
*/
static async digest(take: number = -1) {
const groups = await Group.find({take});
return '当前所在群聊:\n' + groups.map(group => `${group.id} ${group.title} ${group.on}\n`);
return '当前所在群聊:\n' + groups.map(group => `${group.id} ${group.title} ${group.on}`).join('\n') + '\n';
}
}
30 changes: 18 additions & 12 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as TelegramBot from 'node-telegram-bot-api'
import 'reflect-metadata'
import * as typeorm from 'typeorm'
import * as math from 'mathjs'
import { DateTime } from 'luxon/src/datetime'

import { Group } from './entity/Group';
import { chatIsGroup } from './aug'
Expand All @@ -31,8 +32,8 @@ const csm = [
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({level, message, timestamp}) => `${timestamp} ${level.toUpperCase()}: ${message}`),
winston.format.timestamp({ format: () => DateTime.now().toISO() }),
winston.format.printf(({level, message, timestamp}) => `${timestamp} ${level}: ${message}`),
),
transports: [
new winston.transports.Console(),
Expand Down Expand Up @@ -73,20 +74,23 @@ typeorm.createConnection().then(async db => {
let lastReport: Record<number, string> = {};
async function setupReport() {
for (;;) {
const timeout = new Date().getNextHourTimeout(1);
const timeout = DateTime.now().getNextHourTimeout(1);
logger.info(`setup timeout:${timeout}ms`);
await new Promise(resolve => setTimeout(resolve, timeout));
const d = new Date();
const hours12 = d.getHours() % 12;
const d = DateTime.now();
const hours12 = d.hour % 12;
const cur = d.toLocaleDateHoursString();
const groups = await Group.find();
const groups = await Group.find({
select: ['id', 'title'],
where: { on: true },
});
// 等待所有组都发完
await Promise.all(groups.map(async group => {
if (lastReport[group.id] === cur) {
logger.info(`${d.toLocaleString()}${group.id}群友已报时,跳过`);
logger.info(`${d.toLocaleString()}${group.name()}群友已报时,跳过`);
} else {
await bot.sendSticker(group.id, stickers[hours12]);
logger.info(`${d.toLocaleString()}:成功向${group.id}报时`);
logger.info(`${d.toLocaleString()}:成功向${group.name()}报时`);
}
}));
lastReport = {};
Expand Down Expand Up @@ -124,12 +128,14 @@ typeorm.createConnection().then(async db => {
break;
}
case 'baoshi': {
await bot.sendSticker(chat.id, stickers[new Date().getHours() % 12]);
const d = DateTime.now();
await bot.sendSticker(chat.id, stickers[d.hour % 12]);
lastReport[chat.id] = d.toLocaleDateHoursString();
break;
}
case 'time': {
// bot 所处服务器 locale 设为 zh_CN.utf8
await bot.sendMessage(chat.id, new Date().toLocaleString());
await bot.sendMessage(chat.id, DateTime.now().toLocaleString(DateTime.DATETIME_HUGE_WITH_SECONDS));
break;
}
case 'off':
Expand Down Expand Up @@ -169,8 +175,8 @@ typeorm.createConnection().then(async db => {
break;
}
case 'group': {
const d = new Date();
if (stickersInv[sticker.file_id] === d.getHours()) {
const d = DateTime.now();
if (stickersInv[sticker.file_id] === d.hour) {
// 记录群友报时
lastReport[chat.id] = d.toLocaleDateHoursString();
}
Expand Down

0 comments on commit b67efb1

Please sign in to comment.