날짜포멧 수정

This commit is contained in:
Macbook
2026-05-29 02:25:03 +09:00
parent 990b3a0710
commit 03441337f2
19 changed files with 166 additions and 26 deletions
@@ -3,6 +3,7 @@
*/
import React, { useState, useEffect, useCallback } from 'react';
import type { ChartManager } from '../utils/ChartManager';
import { subscribeChartTimeFormat } from '../utils/chartTimeFormat';
const AXIS_HEIGHT = 22;
@@ -26,12 +27,14 @@ const CandlePaneTimeAxis: React.FC<CandlePaneTimeAxisProps> = ({ manager, contai
const unsubLayout = manager.subscribePaneLayout(sync);
const unsubRange = manager.subscribeViewport(sync);
const unsubFormat = subscribeChartTimeFormat(sync);
const timers = [0, 50, 150, 400].map(ms => window.setTimeout(sync, ms));
return () => {
ro.disconnect();
unsubLayout();
unsubRange();
unsubFormat();
timers.forEach(clearTimeout);
};
}, [manager, containerEl, sync]);
+7 -1
View File
@@ -116,6 +116,8 @@ export interface ChartSlotHandle {
/** 거래량 pane on/off */
setVolumeVisible: (visible: boolean) => void;
setPaneSeparatorOptions: (opts: ChartPaneSeparatorOptions) => void;
/** 차트 시간축·크로스헤어 날짜 형식 */
setChartTimeFormat: (format: string, timeframe?: Timeframe) => void;
}
// ── Props ─────────────────────────────────────────────────────────────────
@@ -323,7 +325,11 @@ const ChartSlot = forwardRef<ChartSlotHandle, ChartSlotProps>(function ChartSlot
setPaneSeparatorOptions: (opts: ChartPaneSeparatorOptions) => {
managerRef.current?.setPaneSeparatorOptions(opts);
},
}), []);
setChartTimeFormat: (format: string, tf?: Timeframe) => {
managerRef.current?.setChartTimeFormat(format);
if (tf) managerRef.current?.setDisplayTimezone(displayTimezone ?? 'Asia/Seoul', tf, format);
},
}), [displayTimezone]);
// 자석모드 변경 → ChartManager 크로스헤어 모드 즉시 반영
useEffect(() => {
@@ -71,7 +71,7 @@ const ChartTimeFormatPicker: React.FC<ChartTimeFormatPickerProps> = ({ value, on
<input
type="text"
className="stg-input stg-chart-time-format-custom"
placeholder="예: yyyy-MM-dd HH:mm"
placeholder="예: yyyy-MM-dd HH:mm:ss, dd/MM/yyyy HH:mm"
value={customText}
onChange={e => setCustomText(e.target.value)}
onBlur={commitCustom}
+35 -9
View File
@@ -16,6 +16,7 @@ import IndicatorMainDefaultsPanel, {
import type { IndicatorConfig } from '../types';
import type { PlotDef, HLineDef } from '../utils/indicatorRegistry';
import type { IchimokuCloudColors } from '../utils/ichimokuConfig';
import ChartTimeFormatPicker from './ChartTimeFormatPicker';
import {
TRADE_ALERT_SOUND_OPTIONS,
normalizeTradeAlertSoundId,
@@ -43,7 +44,6 @@ import {
LINE_WIDTH_OPTIONS,
} from '../utils/plotColorUtils';
import TimezonePicker from './TimezonePicker';
import ChartTimeFormatPicker from './ChartTimeFormatPicker';
import AdminPasswordGate from './AdminPasswordGate';
import AdminSettingsPanel from './AdminSettingsPanel';
import {
@@ -155,6 +155,8 @@ interface SettingsPageProps {
onDisplayTimezoneChange?: (tz: string) => void;
chartTimeFormat?: string;
onChartTimeFormatChange?: (format: string) => void;
tradeAlertTimeFormat?: string;
onTradeAlertTimeFormatChange?: (format: string) => void;
menuPermissions?: Record<string, boolean>;
verificationIssueNotify?: boolean;
onVerificationIssueNotify?: (v: boolean) => void;
@@ -550,18 +552,25 @@ const PaperPanel: React.FC<PaperPanelProps> = ({
const GeneralPanel: React.FC<{
displayTimezone: string;
onDisplayTimezoneChange: (tz: string) => void;
chartTimeFormat?: string;
onChartTimeFormatChange?: (format: string) => void;
tradeAlertTimeFormat?: string;
onTradeAlertTimeFormatChange?: (format: string) => void;
verificationIssueNotify?: boolean;
onVerificationIssueNotify?: (v: boolean) => void;
showVerificationNotify?: boolean;
}> = ({
displayTimezone,
onDisplayTimezoneChange,
chartTimeFormat = 'MM-dd HH:mm',
onChartTimeFormatChange,
tradeAlertTimeFormat = 'MM-dd HH:mm',
onTradeAlertTimeFormatChange,
verificationIssueNotify = true,
onVerificationIssueNotify,
showVerificationNotify = true,
}) => {
const [lang, setLang] = useState('ko');
const [dateFormat, setDateFmt] = useState('YYYY-MM-DD');
const [lang, setLang] = useState('ko');
const [startPage, setStart] = useState('chart');
const [animations, setAnim] = useState(true);
const [tooltips, setTool] = useState(true);
@@ -576,12 +585,23 @@ const GeneralPanel: React.FC<{
<option value="ja"></option>
</select>
</SettingRow>
<SettingRow label="날짜 형식" desc="차트 및 UI에서 날짜를 표시하는 방식입니다.">
<select className="stg-select" value={dateFormat} onChange={e => setDateFmt(e.target.value)}>
<option value="YYYY-MM-DD">YYYY-MM-DD</option>
<option value="DD/MM/YYYY">DD/MM/YYYY</option>
<option value="MM/DD/YYYY">MM/DD/YYYY</option>
</select>
<SettingRow
label="날짜·시간 형식"
desc="캔들·보조지표 차트 하단 시간축·크로스헤어에 적용됩니다. 프리셋 선택 또는 직접 입력(토큰: yyyy, yy, MM, dd, HH, mm, ss)이 가능합니다."
>
<ChartTimeFormatPicker
value={chartTimeFormat}
onChange={fmt => onChartTimeFormatChange?.(fmt)}
/>
</SettingRow>
<SettingRow
label="매매 시그널 알림 시간 형식"
desc="매매 시그널 알림 팝업·상세에 표시되는 캔들·수신 시각 형식입니다. 프리셋 선택 또는 직접 입력이 가능합니다."
>
<ChartTimeFormatPicker
value={tradeAlertTimeFormat}
onChange={fmt => onTradeAlertTimeFormatChange?.(fmt)}
/>
</SettingRow>
<SettingRow label="시간대" desc="차트·하단 시계·알림에 사용되는 표시 시간대입니다.">
<TimezonePicker
@@ -1598,6 +1618,8 @@ const SettingsPage: React.FC<SettingsPageProps> = ({
onDisplayTimezoneChange,
chartTimeFormat = 'MM-dd HH:mm',
onChartTimeFormatChange,
tradeAlertTimeFormat = 'MM-dd HH:mm',
onTradeAlertTimeFormatChange,
menuPermissions,
verificationIssueNotify = true,
onVerificationIssueNotify,
@@ -1688,6 +1710,10 @@ const SettingsPage: React.FC<SettingsPageProps> = ({
<GeneralPanel
displayTimezone={displayTimezone}
onDisplayTimezoneChange={onDisplayTimezoneChange ?? (() => {})}
chartTimeFormat={chartTimeFormat}
onChartTimeFormatChange={onChartTimeFormatChange}
tradeAlertTimeFormat={tradeAlertTimeFormat}
onTradeAlertTimeFormatChange={onTradeAlertTimeFormatChange}
verificationIssueNotify={verificationIssueNotify}
onVerificationIssueNotify={onVerificationIssueNotify}
showVerificationNotify={menuPermissions == null || menuPermissions['verification-board'] === true}
+4 -5
View File
@@ -2,7 +2,8 @@
import React, { useState } from 'react';
import { useDraggablePanel } from '../hooks/useDraggablePanel';
import { placePaperOrder, placeLiveOrder, loadLiveSummary } from '../utils/backendApi';
import { formatUnixDateTime } from '../utils/timezone';
import { formatSignalTime } from '../utils/tradeSignalDisplay';
import { useTradeAlertTimeFormat } from '../utils/tradeAlertTimeFormat';
export interface TradeSignalInfo {
market: string;
@@ -30,9 +31,6 @@ interface Props {
const fmt = (n: number): string =>
n > 0 ? n.toLocaleString('ko-KR', { maximumFractionDigits: 0 }) : '0';
function fmtTime(unix: number): string {
return formatUnixDateTime(unix);
}
function execLabel(type?: string, candleType?: string): string {
const base = type === 'REALTIME_TICK' ? '실시간 틱' : '봉 마감';
@@ -61,6 +59,7 @@ export const TradeAlertModal: React.FC<Props> = ({
paperAutoTradeBudgetPct = 95,
onOrderDone,
}) => {
useTradeAlertTimeFormat();
const isBuy = signal.signalType === 'BUY';
const accentColor = isBuy ? '#3f7ef5' : '#ef5350';
const accentGlow = isBuy ? 'rgba(63,126,245,0.22)' : 'rgba(239,83,80,0.22)';
@@ -197,7 +196,7 @@ export const TradeAlertModal: React.FC<Props> = ({
</span>
</div>
<div className="tam-price-time">
: {fmtTime(signal.candleTime)}
: {formatSignalTime(signal.candleTime)}
</div>
</div>
@@ -9,6 +9,7 @@ import {
getSignalTypeKo,
type TradeSignalDisplaySource,
} from '../utils/tradeSignalDisplay';
import { useTradeAlertTimeFormat } from '../utils/tradeAlertTimeFormat';
interface Props {
item: TradeSignalDisplaySource;
@@ -22,6 +23,7 @@ export const TradeSignalDetailBody: React.FC<Props> = ({
variant = 'compact',
showHeadline = true,
}) => {
useTradeAlertTimeFormat();
const isBuy = item.signalType === 'BUY';
const rows = buildSignalDetailRows(item);
+1
View File
@@ -1026,6 +1026,7 @@ const TradingChart: React.FC<TradingChartProps> = ({
useEffect(() => {
managerRef.current?.setDisplayTimezone(displayTimezone, timeframe, chartTimeFormat);
managerRef.current?.setChartTimeFormat(chartTimeFormat);
}, [displayTimezone, timeframe, chartTimeFormat]);
// 종목·타임프레임 변경 시 barsKey 캐시만 초기화 (reloadAll 은 bars effect 에서 1회만)
@@ -16,6 +16,7 @@ import {
getMarketDisplayLine,
getSignalTypeKo,
} from '../../utils/tradeSignalDisplay';
import { useTradeAlertTimeFormat } from '../../utils/tradeAlertTimeFormat';
import {
buildStrategyChartIndicators,
candleTypeToTimeframe,
@@ -66,6 +67,7 @@ const TradeNotificationListRow: React.FC<Props> = ({
onDetail,
onGoToChart,
}) => {
useTradeAlertTimeFormat();
const isBuy = item.signalType === 'BUY';
const allDetailRows = buildSignalDetailRows(item);
const metaRows = allDetailRows.filter(