fix: Asia/Seoul 타임존 지원을 위해 luxon 라이브러리 도입
- backend/routes/todos.js: 오늘의 할일 조회 시 KST 기준으로 날짜 계산 - backend/routes/schedules.js: 주간/월간 일정 조회 시 KST 기준으로 날짜 범위 계산 - backend/routes/bible.js: 오늘의 성경 구절 조회 시 KST 기준으로 날짜 계산 - flutter_app: Mock 데이터 사용 시 타임존 관련 주석 추가
This commit is contained in:
10
backend/package-lock.json
generated
10
backend/package-lock.json
generated
@@ -13,6 +13,7 @@
|
|||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"googleapis": "^171.0.0",
|
"googleapis": "^171.0.0",
|
||||||
|
"luxon": "^3.7.2",
|
||||||
"mongoose": "^8.9.0",
|
"mongoose": "^8.9.0",
|
||||||
"multer": "^1.4.5-lts.1"
|
"multer": "^1.4.5-lts.1"
|
||||||
}
|
}
|
||||||
@@ -1273,6 +1274,15 @@
|
|||||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/luxon": {
|
||||||
|
"version": "3.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
|
||||||
|
"integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/math-intrinsics": {
|
"node_modules/math-intrinsics": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"googleapis": "^171.0.0",
|
"googleapis": "^171.0.0",
|
||||||
|
"luxon": "^3.7.2",
|
||||||
"mongoose": "^8.9.0",
|
"mongoose": "^8.9.0",
|
||||||
"multer": "^1.4.5-lts.1"
|
"multer": "^1.4.5-lts.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
|
const { DateTime } = require("luxon");
|
||||||
const BibleVerse = require("../models/BibleVerse");
|
const BibleVerse = require("../models/BibleVerse");
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
// Korea Standard Time zone
|
||||||
|
const KST_TIMEZONE = "Asia/Seoul";
|
||||||
|
|
||||||
const pickRandomVerse = async (filter) => {
|
const pickRandomVerse = async (filter) => {
|
||||||
const results = await BibleVerse.aggregate([
|
const results = await BibleVerse.aggregate([
|
||||||
{ $match: filter },
|
{ $match: filter },
|
||||||
@@ -13,7 +17,9 @@ const pickRandomVerse = async (filter) => {
|
|||||||
|
|
||||||
router.get("/today", async (req, res) => {
|
router.get("/today", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const targetDate = req.query.date || new Date().toISOString().slice(0, 10);
|
// Get today's date in KST (YYYY-MM-DD format)
|
||||||
|
const todayKst = DateTime.now().setZone(KST_TIMEZONE).toISODate();
|
||||||
|
const targetDate = req.query.date || todayKst;
|
||||||
const datedVerse = await pickRandomVerse({
|
const datedVerse = await pickRandomVerse({
|
||||||
active: true,
|
active: true,
|
||||||
date: targetDate,
|
date: targetDate,
|
||||||
|
|||||||
@@ -1,31 +1,35 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
|
const { DateTime } = require("luxon");
|
||||||
const Schedule = require("../models/Schedule");
|
const Schedule = require("../models/Schedule");
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
const startOfWeek = (date = new Date()) => {
|
// Korea Standard Time zone
|
||||||
const copy = new Date(date);
|
const KST_TIMEZONE = "Asia/Seoul";
|
||||||
const day = copy.getDay();
|
|
||||||
const diff = day === 0 ? -6 : 1 - day;
|
const startOfWeek = () => {
|
||||||
copy.setDate(copy.getDate() + diff);
|
// Get current time in KST and find the start of the week (Monday)
|
||||||
copy.setHours(0, 0, 0, 0);
|
const nowKst = DateTime.now().setZone(KST_TIMEZONE);
|
||||||
return copy;
|
// Luxon uses 1 = Monday, 7 = Sunday
|
||||||
|
const startOfWeekKst = nowKst.startOf("week"); // Monday 00:00:00.000
|
||||||
|
return startOfWeekKst.toJSDate();
|
||||||
};
|
};
|
||||||
|
|
||||||
const endOfWeek = (date = new Date()) => {
|
const endOfWeek = () => {
|
||||||
const start = startOfWeek(date);
|
// Get current time in KST and find the end of the week (Sunday)
|
||||||
const end = new Date(start);
|
const nowKst = DateTime.now().setZone(KST_TIMEZONE);
|
||||||
end.setDate(end.getDate() + 6);
|
const endOfWeekKst = nowKst.endOf("week"); // Sunday 23:59:59.999
|
||||||
end.setHours(23, 59, 59, 999);
|
return endOfWeekKst.toJSDate();
|
||||||
return end;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const startOfMonth = (date = new Date()) => {
|
const startOfMonth = () => {
|
||||||
return new Date(date.getFullYear(), date.getMonth(), 1, 0, 0, 0, 0);
|
const nowKst = DateTime.now().setZone(KST_TIMEZONE);
|
||||||
|
return nowKst.startOf("month").toJSDate();
|
||||||
};
|
};
|
||||||
|
|
||||||
const endOfMonth = (date = new Date()) => {
|
const endOfMonth = () => {
|
||||||
return new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59, 999);
|
const nowKst = DateTime.now().setZone(KST_TIMEZONE);
|
||||||
|
return nowKst.endOf("month").toJSDate();
|
||||||
};
|
};
|
||||||
|
|
||||||
router.get("/", async (req, res) => {
|
router.get("/", async (req, res) => {
|
||||||
|
|||||||
@@ -1,27 +1,26 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
|
const { DateTime } = require("luxon");
|
||||||
const Todo = require("../models/Todo");
|
const Todo = require("../models/Todo");
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// Get day range in Korea Standard Time (UTC+9)
|
// Korea Standard Time zone
|
||||||
|
const KST_TIMEZONE = "Asia/Seoul";
|
||||||
|
|
||||||
|
// Get day range in Korea Standard Time (Asia/Seoul)
|
||||||
const getDayRange = () => {
|
const getDayRange = () => {
|
||||||
const now = new Date();
|
// Get current time in KST
|
||||||
// Get current time in KST (UTC+9)
|
const nowKst = DateTime.now().setZone(KST_TIMEZONE);
|
||||||
const kstOffset = 9 * 60; // minutes
|
|
||||||
const utcTime = now.getTime() + (now.getTimezoneOffset() * 60000);
|
|
||||||
const kstTime = new Date(utcTime + (kstOffset * 60000));
|
|
||||||
|
|
||||||
// Start of day in KST
|
// Start of day in KST (00:00:00.000)
|
||||||
const startKst = new Date(kstTime);
|
const startOfDayKst = nowKst.startOf("day");
|
||||||
startKst.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
// End of day in KST
|
// End of day in KST (23:59:59.999)
|
||||||
const endKst = new Date(kstTime);
|
const endOfDayKst = nowKst.endOf("day");
|
||||||
endKst.setHours(23, 59, 59, 999);
|
|
||||||
|
|
||||||
// Convert back to UTC for MongoDB query
|
// Convert to JavaScript Date objects (UTC) for MongoDB query
|
||||||
const start = new Date(startKst.getTime() - (kstOffset * 60000));
|
const start = startOfDayKst.toJSDate();
|
||||||
const end = new Date(endKst.getTime() - (kstOffset * 60000));
|
const end = endOfDayKst.toJSDate();
|
||||||
|
|
||||||
return { start, end };
|
return { start, end };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class TodoService {
|
|||||||
|
|
||||||
Future<List<TodoItem>> fetchTodayTodos() async {
|
Future<List<TodoItem>> fetchTodayTodos() async {
|
||||||
if (ApiConfig.useMockData) {
|
if (ApiConfig.useMockData) {
|
||||||
|
// Using device's local timezone (should be Asia/Seoul for Korean users)
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
final today = DateTime(now.year, now.month, now.day);
|
final today = DateTime(now.year, now.month, now.day);
|
||||||
final tomorrow = today.add(const Duration(days: 1));
|
final tomorrow = today.add(const Duration(days: 1));
|
||||||
|
|||||||
Reference in New Issue
Block a user