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

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

조회 173회 댓글 0건
  • 현재 페이지 주소 복사
  • 페이스북으로 공유
  • X 로  공유
  • 트위터로  공유
  • 네이버 블로그로 공유
  • 네이버 카페 공유하기
  • 네이버 라인 공유하기
  • 네이버 밴드 공유하기
  • 링크드인으로 공유하기
  • 핀터레스트에 공유하기

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 이면 별도로 이렇게 왔다 갔다 하면서 처리할 필요는 없습니다.

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



  • 현재 페이지 주소 복사
  • 페이스북으로 공유
  • X 로  공유
  • 트위터로  공유
  • 네이버 블로그로 공유
  • 네이버 카페 공유하기
  • 네이버 라인 공유하기
  • 네이버 밴드 공유하기
  • 링크드인으로 공유하기
  • 핀터레스트에 공유하기
전체 238건 1 페이지
  • profile_image AL3에서는 패키지가 제공되지 아니하기 때문에 PHP 7.4 버전이 필요하다면 php-fpm을 소스를 받아 컴파일 하는 방법을 사용해야 됩니다.5시간은 걸린것 같은데 아래 사용하시면 시간을 대폭 줄일 수 있으니 필요하신분 참고하시면 되고 문제가 있었던 부분은 openssl 입니다. PHP 7.4에서 사용해야 되는 openSSL 버전과 현재 서버에 설치되어 있는 OpenSSL 버전이 차이가 있어서 컴파일 과정에서 오류가 발생 하는데 이 문제인지 확인 하는 방법은 끝에 적어 놓은것 처럼 openssl만 빼고 컴파일해보세요. 잘 된다면 정확히 openssl 버전의 문제 입니다. ## 소스 컴파일에 필요한 패…
  • profile_image PHP 설치 되어 있지 아니하여 윈도우PC에 최신버전으로 설치버전은 설치 할 때마다 다르기 때문에 본인이 사용하려는버전을 선택 하면 됩니다.     > 현대적인? 방법으로 설치함.       예전에 압축해 놓은것 풀고 path 설정하고 했던 그런 방법을 쓰지 않고 간단하게 설치가 되었다.      winget install PHP.PHP.8.5    > 아래 명령으로 설치된 위치를 찾음      where php    > php.ini-production…
  • profile_image OP캐쉬 사용하면 괜찮아 보다는 저 같은 경우는 사용하지 않아도 괜찮아를 더 좋아 합니다.▷ 솔리드 캐시(SOLID CACHE)란?솔리드 캐시는 간단히 말해 "비싼 RAM(REDIS) 대신 저렴하고 넉넉한 디스크(DB)에 캐시를 저장하는 전략"으로 원래 루비 온 레일즈(RUBY ON RAILS) 커뮤니티에서 제안된 방식이지만 본질은 어떤 언어에서든 적용 가능한 실용적인 캐싱 철학임.▷ 핵심 철학: "ssd는 생각보다 훨씬 빠르다"과거에는 디스크가 너무 느려서 무조건 데이터를 ram(REDIS MEMCACHED)에 올려야 했지만 지금은 nvme ssd 같은 초고속 저장 장치가 보편화되었습니다. 굳이 복잡하게 별도의 메모리…
  • profile_image MyISAM은 SELECT가 빠르고 InnoDB는 느리다그런 경우도 있고 아닌 경우도 있기 때문에 어떤 용도로 사용하느냐에 따라서 다를 수 있습니다.그리고 처음 데이터 넣은 다음 select만 90% 이상이고 테이블 사용이 업데이트나 인서트는 적은 경우인지 불특정 다수에게 서비스 하기 때문에 불특정한 row를 가져와서 보여줘야 하는것인지에 다를 수 있는 것입니다. 가장 큰 차이: 데이터와 인덱스 구조→ MyISAM  - 데이터 파일(.MYD) 과 인덱스 파일(.MYI) 이 분리됨  - 인덱스 → 데이터 파일을 다시 읽는 구조  - 동작흐름: PK 인덱스 탐색 (.MYI) -> 데이터 위치…
  • profile_image 데이터베이스를 사용하다 보면 이미 존재하는 데이터인지 확인한 후 INSERT 또는 UPDATE를 해야 하는 상황을 자주 만나게 됩니다.이때 매우 유용한 문법이 바로 INSERT ... ON DUPLICATE KEY UPDATE입니다.즉, 쿼리 한번으로 해결 된다는 의미 인데 아무곳에서나 사용 가능한것은 아니고 키 중복이 발생하는 부분에서만 사용 하는 것입니다.그렇기 때문에 unique의 특성을 모르시는 분은 사용 하면 안되겠지요.  장점- 쿼리 수 감소: SELECT → INSERT/UPDATE 두 번 쿼리 날릴 필요 없음- 동시성 문제 감소: SELECT 후 INSERT 방식보다 Race Condition 발…
  • profile_image 웹서버에 접근하는 X-Forwarded-For란?X-Forwarded-For(XFF)는 HTTP 헤더로 클라이언트가 프록시나 로드 밸런서를 거쳐 웹 서버에 접속할 때 원래 클라이언트의 IP 주소를 식별하기 위해 사용 됩니다.로그밸런스도 프록시서버의 변형된 형태가 있기 때문에 쉽게 프록시 서버라고 생각을 하면 쉽습니다.일반적으로 웹 서버는 직접 연결된 IP만 볼 수 있는데 프록시 뒤에 있으면 프록시 서버의 IP만 보이게 되는데 이런 경우 XFF 헤더가 실제 사용자 IP를 전달하는 역할을 합니다. ▷ 헤더 형식X-Forwarded-For: 클라이언트IP 프록시1 프록시2 ...여러 프록시를 거치면 쉼표로 구분되어 …
  • profile_image ifconfig는 초기 한번 정도만 사용하고 interface configuration의 약자로 리눅스/유닉스 시스템에서 네트워크 인터페이스를 설정하고 확인하는 명령어입니다.▷ ifconfig 주요 용도1. 네트워크 인터페이스 정보 조회  - 현재 활성화된 네트워크 인터페이스 목록 확인  - 각 인터페이스의 IP 주소, MAC 주소, 서브넷 마스크 확인  - 네트워크 통계 정보 (전송/수신 패킷 수, 에러 등) 확인2. 네트워크 인터페이스 설정  - IP 주소 할당 및 변경  - 서브넷 마스크 설정  - 브로드캐스트 주소 설정  - MTU(Maximum Tr…

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