csv 파일 특정일자를 기준으로 다른파일 다음날짜
csv파일 읽어서 처리할 때 날짜를 기준으로 하는데 같은 날짜가 아니라 다른 날짜로 처리 해야 되는 경우 만들어진 프로그램 입니다.
csv파일의 캐릭터셋에 대해선 별도 정리가 필요한 상태이고 윈도우10 사용한지 오래 되었는데 이 문제가 업그레이드 되면서 변경 되었는지 어땟는지는 현재로선 중요하지 않고 잘 나오면 그만인거죠
cmd도 예전엔 cp949로해서 처리 했는데 지금은 둘다 잘 보이는 구조로 되어 있는듯 합니다.
그리고 엑셀은 euckr, utf-8 bom 두개가 문제 없으며 utf-8은 안됩니다.
<?php
// 공휴일 배열
$holidays = [
"2025-01-01", // 신정
"2025-02-11", // 설날 (임의로 지정, 실제로는 음력 기준)
"2025-03-01", // 삼일절
];
// 다음 영업일을 계산하는 함수
function getNextBusinessDay($date, $holidays) {
$datetime = new DateTime($date);
do {
$datetime->modify('+1 day');
$dayOfWeek = $datetime->format('N'); // 1(월) ~ 7(일)
$currentDate = $datetime->format('Y-m-d');
} while ($dayOfWeek > 5 || in_array($currentDate, $holidays)); // 주말이거나 공휴일이면 건너뜀
return $currentDate;
}
// CSV 파일 읽기 함수
function readCSV($filename) {
$data = [];
if (($handle = fopen($filename, "r")) !== FALSE) {
// 첫 줄 (헤더) 읽기
$header = fgetcsv($handle);
// print_r($header);
foreach( $header as $key => $value ) {
// $header[$key] = mb_convert_encoding($value, 'EUC-KR', 'UTF-8');
}
// print_r($header);
// exit;
while (($row = fgetcsv($handle)) !== FALSE) {
foreach( $row as $key => $value ) {
// $row[$key] = mb_convert_encoding($value, 'EUC-KR', 'UTF-8');
$row[$key] = trim($value);
$row[$key] = str_replace(' ', '', $row[$key]);
}
$data[$row[0]] = $row; // 날짜를 키로 사용
}
fclose($handle);
}
return [$header, $data];
}
// EWY와 KODEX200 데이터 병합
function mergeData($qqqData, $ewyData, $kodexData, $holidays) {
$merged = [];
foreach ($ewyData as $date => $ewyRow) {
$ewyDate = new DateTime($date);
$nextBusinessDay = getNextBusinessDay($date, $holidays);
// KODEX200에 해당 날짜가 있는지 확인
if (isset($kodexData[$nextBusinessDay])) {
if ( isset($qqqData[$date])) {
$qqqRow = $qqqData[$date];
$merged[$date] = array_merge($qqqRow, $ewyRow, $kodexData[$nextBusinessDay]);
}
}
}
return $merged;
}
function remove_utf8_bom($text) {
if (substr($text, 0, 3) === "\xEF\xBB\xBF") {
return substr($text, 3);
}
return $text;
}
// 메인 실행
$ewyFile = 'ewy-2021.csv';
$kodexFile = 'kodex200-2021.csv';
$qqqFile = 'qqq-2021.csv';
$ewy_utf8 = file_get_contents($ewyFile) or die("'$ewyFile' 파일을 찾을 수 없습니다.");
$ewy_utf8 = remove_utf8_bom($ewy_utf8);
$kodex_utf8 = file_get_contents($kodexFile) or die("'$kodexFile' 파일을 찾을 수 없습니다.");
$kodex_utf8 = remove_utf8_bom($kodex_utf8);
$qqq_utf8 = file_get_contents($qqqFile) or die("'$qqqFile' 파일을 찾을 수 없습니다.");
$qqq_utf8 = remove_utf8_bom($qqq_utf8);
$ewy_euckr = mb_convert_encoding($ewy_utf8, 'EUC-KR', 'UTF-8');
$kodex_euckr = mb_convert_encoding($kodex_utf8, 'EUC-KR', 'UTF-8');
$qqq_euckr = mb_convert_encoding($qqq_utf8, 'EUC-KR', 'UTF-8');
$ewyFile_euckr = 'ewy-2021-euckr.csv';
$kodexFile_euckr = 'kodex200-2021-euckr.csv';
$qqqFile_euckr = 'qqq-2021-euckr.csv';
file_put_contents($ewyFile_euckr, $ewy_euckr);
file_put_contents($kodexFile_euckr, $kodex_euckr);
file_put_contents($qqqFile_euckr, $qqq_euckr);
// echo $qqq_euckr; exit;
// CSV 파일 읽기
list($ewyHeader, $ewyData) = readCSV($ewyFile_euckr);
list($kodexHeader, $kodexData) = readCSV($kodexFile_euckr);
list($qqqHeader, $qqqData) = readCSV($qqqFile_euckr);
// print_r($qqqHeader);
// EXIT;
// 헤더 결합
$combinedHeader = array_merge($qqqHeader, $ewyHeader, $kodexHeader);
// foreach( $combinedHeader as $key => $value ) {
// $combinedHeader[$key] = mb_convert_encoding($value, 'UTF-8', 'EUC-KR');
// $combinedHeader[$key] = trim($value);
// }
// print_r($combinedHeader);
// exit;
// 데이터 병합
$mergedData = mergeData($qqqData, $ewyData, $kodexData, $holidays);
// foreach( $mergedData as $key => $value ) {
// foreach( $value as $key2 => $value2 ) {
// $mergedData[$key][$key2] = mb_convert_encoding($value2, 'UTF-8', 'EUC-KR');
// }
// }
// print_r($mergedData);
// exit;
// 결과 CSV 파일 쓰기
$outputFile = 'merged_etf_data.csv';
$fp = fopen($outputFile, 'w');
fputcsv($fp, $combinedHeader);
foreach ($mergedData as $row) {
fputcsv($fp, $row);
}
fclose($fp);
$mergedData_euckr = file_get_contents($outputFile);
$mergedData_utf8 = mb_convert_encoding($mergedData_euckr, 'UTF-8', 'EUC-KR');
$outputFile = 'merged_etf_data_utf8bom.csv';
file_put_contents($outputFile, "\xEF\xBB\xBF" . $mergedData_utf8);
echo "데이터 병합이 완료되었습니다. 결과는 '$outputFile'에 저장되었습니다.\n";
프로그램은 필요하신분 날짜 처리 하는 부분만 참고하면 되며 파일 자체가 cp949 이면 별도로 이렇게 왔다 갔다 하면서 처리할 필요는 없습니다.
터미널, 에디터, 엑셀 모두 다 잘맛아야 프로그램 하면서 착각을 하지 않습니다...