csv 파일 특정일자를 기준으로 다른파일 다음날짜 > PHP
PHP

csv 파일 특정일자를 기준으로 다른파일 다음날짜

조회 70회 댓글 0건

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";
 


639312927dff10c63be22075a759729f_1740880339_1944.png
 


프로그램은 필요하신분 날짜 처리 하는 부분만 참고하면 되며 파일 자체가 cp949 이면 별도로 이렇게 왔다 갔다 하면서 처리할 필요는 없습니다.

터미널, 에디터, 엑셀 모두 다 잘맛아야 프로그램 하면서 착각을 하지 않습니다...



  • 페이스북으로 공유
  • 트위터로  공유
  • 구글플러스로 공유
전체 215건 1 페이지
  • profile_image 아래 프로그램 실행전에 앱키와 시크릿키는 API키 발급 받는곳에서 먼저 받아 놓아야 합니다.키움증권 REST API 사용신청 하는곳API 사용신청 | 키움 REST API REST는 특성성 프로그램 언어와 관계 없습니다. 예제에서 파이선 자바스크립트 이렇게 있고 PHP 없다고 하여 안되는것이 아닙니다.물론 인터넷(네트워크) 지원 안되는 언어는 안됩니다.그렇기 때문에 리눅스 쉘에서 쉽게 테스트 할 수 있는 아래도 당연히 됩니다.curl -X POST -H "Content-Type: application/json;charset=UTF-8" -d '{"grant_type":"client_credentials","appkey"…
  • profile_image 쉽게 한번만 사용할거냐 여러번 사용할거냐에 대한 차이라고 생각해도 됩니다.특별한 경우가 아니라면 다목적으로 사용이 가능한 bindParam 를 많이 사용 합니다. 구분해서 사용하려면 또 신경을 써야 하기 때문에 그렇죠▶ bindParam() (참조 바인딩)  - 변수 자체를 바인딩 (이후 변수 값이 바뀌면 SQL 실행 시 그 값이 적용됨)  - 변수를 직접 전달해야 하고 즉시 값 대입이 불가능  - 반복문에서 같은 변수를 여러 번 사용할 경우 적합. 그리고 파라미터는 상수가 아니라 변수를 넣어줘야 합니다.△ 비유: 패스트푸드점에서 "세트 메뉴 1번"을 주문하고, 음료는 나중에 결정할 수 있는 방식    $menu = "…
  • profile_image 아래는 쿼리 문장에 문자열을 넣어주는 일반적인 방식으로 SQL 공격에 무척 취약한 방식의 예 입니다.보통 아래와 같은 문제가 발생하고 실무에선 쿼리를 보면 먼저 정보를 얻는것에서 시작을 합니다.    # SQL 인젝션이 성공하는 경우 (취약한 코드)    # 결과: SELECT * FROM users WHERE username = ''; DROP TABLE users; -- AND id = 123    $test11 = "'; DROP TABLE users; --";    $test22 = 123;    $sql = "SELECT * FROM users WHERE username = '$test11' AND id = $…
  • profile_image 문자열:s 숫자:i 이렇게 사용하는 방식은 파라미터가 많으면 복잡해서 알아보기 힘들죠그래서 만들어진 사용자 함수 입니다.    # MySQLi에서 Named Parameter처럼 사용할 수 있도록 변환하는 사용자 함수    function prepareNamedQuery($mysqliCon, string $sql, $params) {        preg_match_all('/:\w+/', $sql, $matches);        $namedParams = $matches[0];         $sql = str_replace($namedParams, '?', $sql);        $values = [];     …
  • profile_image 아래는 도메인 목록을 배열로 가지고 있다고 가정하고 만들어진 프로그램 입니다.kr의 경우 요즘은 utf8로 나오기 때문에 euckr 환경이신분은들은 캐릭터셋을 변경하는 기능이 한줄 더 들어가야 합니다.그리고 후이즈 조회는 너무 많이 하면 차단 됩니다.여기서 너무 많다는 기준은 없지만 최소 몇 백은 되기 때문에 도메인 만료일 체크하기 위해서 실행하는것에는 문제는 없습니다.    # 루트 도메인만 추출    $root_domains = [];    foreach ($domains as $domain) {        if ($domain === '_default_') continue; // 제외        if (preg…
  • profile_image 앞으로 캐릭터셋은 utf-8이 아니라 utf-8 bom을 사용해야 합니다. utf-8 캐릭터셋은 한글이 깨져서 보이는데 이때문에 예전에 ANSI로 저장(euc-kr) 처리를 많이 하곤 했습니다. 하지만 현재는 utf-8과 호환되는 utf-8 bom 사용하는 것이 좋겠지요.그래야 더 풍부한 캐릭터셋 특수문자(이모티콘)를 사용할 수 있기 때문에 그렇습니다. euc-kr은 이모티콘을 사용하지 못해요~ 엑셀(Excel)에서 CSV 파일 한글 깨지지 않게 하려면  - 엑셀에서 바로 CSV 열기: EUC-KR 또는 UTF-8 BOM 캐릭터셋 참고사항  - 글로벌 호환성 생각: UTF-8 BOM  - 서버 시스템 처리 위주: UTF…

상업적 이용 금지. 컨텐츠는 개인 용도로만 사용이 가능 합니다.