From 24eeb178bd7f551888241ae0e1df47b60833bf91 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 23 Oct 2026 17:14:25 +0900 Subject: [PATCH] Display Q&A timestamps in Korea time --- egbim/app.js | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/egbim/app.js b/egbim/app.js index c1dc488..53d99fc 100644 --- a/egbim/app.js +++ b/egbim/app.js @@ -61,6 +61,24 @@ return ""; } + function formatKoreanDateTime(value, includeTime) { + const raw = String(value == null ? '' : value).trim(); + if (!raw) return ''; + if (/^\d{4}-\d{2}-\d{2}$/.test(raw)) return raw; + let timestamp = raw.replace(' ', 'T'); + if (!/[zZ]$|[+-]\d{2}:?\d{2}$/.test(timestamp)) timestamp += 'Z'; + const date = new Date(timestamp); + if (Number.isNaN(date.getTime())) return raw; + const options = { timeZone: 'Asia/Seoul', year: 'numeric', month: '2-digit', day: '2-digit' }; + if (includeTime) Object.assign(options, { hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }); + const parts = new Intl.DateTimeFormat('en-CA', options).formatToParts(date).reduce(function (result, part) { + result[part.type] = part.value; + return result; + }, {}); + const day = parts.year + '-' + parts.month + '-' + parts.day; + return includeTime ? day + ' ' + parts.hour + ':' + parts.minute : day; + } + function toBoolean(value) { if (value === true || value === 1) return true; return ["true", "1", "yes", "y"].indexOf(String(value || "").trim().toLowerCase()) > -1; @@ -104,7 +122,8 @@ author: value(["requester_name", "author_name", "authorName", "name", "author"]) || "작성자", title: value(["title", "subject"]) || "제목 없음", content: value(["contents", "content", "body"]) || "", - date: String(createdAt).slice(0, 10), + date: formatKoreanDateTime(createdAt, false), + dateTime: formatKoreanDateTime(createdAt, true), createdAt: createdAt, status: normalizeStatus(value(["feedback_status", "feedbackStatus", "status_code", "status"])), secret: toBoolean(secret), @@ -483,7 +502,7 @@ "" + number + "" + escapeHtml(post.category.replace("문의", "")) + "" + "" + escapeHtml(company) + "" + escapeHtml(post.department) + "" + escapeHtml(post.author) + "" + "" + (post.secret ? "🔒" : "") + escapeHtml(post.title) + "" + (!isNotice && post.date === "2026-09-17" ? "N" : "") + "" + - "" + escapeHtml(post.date) + "" + (status ? "" + escapeHtml(status) + "" : "-") + ""; + "" + escapeHtml(post.dateTime || post.date) + "" + (status ? "" + escapeHtml(status) + "" : "-") + ""; }).join(""); qsa("#qaRows tr").forEach(function (row) { row.addEventListener("click", function () { window.location.href = "detail.html?id=" + encodeURIComponent(row.dataset.id); }); }); pagination.innerHTML = Array.from({ length: totalPages }, function (_, i) { return ""; }).join(""); @@ -527,7 +546,7 @@ if (!qs('#category').value || !title || !content) { errorBox.textContent = '구분, 제목, 내용을 모두 입력해주세요.'; errorBox.style.display = 'block'; return; } const feedbackId = makeUuid(); const createdAt = new Date().toISOString(); - const post = { id: feedbackId, feedbackId: feedbackId, requesterId: currentUser.requesterId, requesterTenantId: currentUser.requesterTenantId, category: qs('#category').value, company: currentUser.company || currentUser.tenantName || currentUser.familyCompany || '외부 사용자', department: currentUser.department || '-', author: currentUser.name || currentUser.loginId, title: title, date: createdAt.slice(0, 10), createdAt: createdAt, status: '신규', secret: qs('#secret').checked, content: content }; + const post = { id: feedbackId, feedbackId: feedbackId, requesterId: currentUser.requesterId, requesterTenantId: currentUser.requesterTenantId, category: qs('#category').value, company: currentUser.company || currentUser.tenantName || currentUser.familyCompany || '외부 사용자', department: currentUser.department || '-', author: currentUser.name || currentUser.loginId, title: title, date: formatKoreanDateTime(createdAt, false), dateTime: formatKoreanDateTime(createdAt, true), createdAt: createdAt, status: '신규', secret: qs('#secret').checked, content: content }; const submitButton = qs('#submitButton'); submitButton.disabled = true; submitButton.textContent = '등록 중...'; @@ -584,7 +603,7 @@ statusElement.classList.toggle("review", status !== "완료"); }; renderDetailStatus(); - qs('[data-detail-date]').textContent = post.date; + qs('[data-detail-date]').textContent = post.dateTime || post.date; qs('[data-detail-author]').textContent = post.author; let detailUser = getAuthUser(); qs('[data-detail-company]').textContent = getPostCompanyLabel(post, detailUser); @@ -731,7 +750,7 @@ return { id: comment.id || '', author: comment.author_name || comment.authorName || comment.author?.name || comment.author || '작성자', - date: comment.created_at || comment.createdAt || comment.updated_at || '', + date: formatKoreanDateTime(comment.created_at || comment.createdAt || comment.updated_at || '', true), content: comment.content || comment.body || '', attachments: (Array.isArray(rawAttachments) ? rawAttachments : [rawAttachments]).map(normalizeAttachment) };