2017-02-06 3 views
2

데이터베이스에 두 개의 필드가 저장되어 있는데 그 중 하나는 datetime을 포함하고 다른 하나는 ISO-8601 형식의 지속 기간을 나타내는 문자열을 포함합니다 (예 : "P1MT2H"). . SQL의 datetime 열에 기간을 추가 할 수 있기를 원하며이 작업을 DATE_ADD을 사용하여 수행 할 수 있어야하는 것처럼 보일 수 있지만이를 간격으로 변환하는 좋은 방법이 있는지는 알 수 없습니다. 가능한 경우 간격을 분석하는 자체 SQL 함수를 정의하지 않아도됩니다.MySQL - DATE_ADD에 대해 ISO-8601 기간을 간격으로 변환

+0

'P1MT2D'는 무엇을 의미합니까? 전에이 형식을 본 적이 없습니다. 링크를 포함 할 수 있습니까? –

+0

https://en.wikipedia.org/wiki/ISO_8601#Durations –

+0

게시했을 때 꽤 지쳤습니다. 기간을 수정했습니다. – sgcharlie

답변

0

나는이 질문에 대한 멋진 답변을 듣고 싶지만, 당분간이 작업을 수행 할 함수를 만들었습니다. 특정 시간대에 계산을 실행하는 세 번째 선택적 매개 변수를 추가했습니다. 그것은 보편적 인 해결책이 아니지만 나는 다른 사람을 바른 길로 인도하기를 바랍니다.

CREATE FUNCTION ADD_ISO_DURATION(StartDate DATETIME, Duration VARCHAR(45), Timezone VARCHAR(45)) 
RETURNS DATETIME 
BEGIN 
    DECLARE TimeStr VARCHAR(45) DEFAULT ''; 
    DECLARE Pos INTEGER; 

    IF StartDate IS NULL OR Duration IS NULL OR LENGTH(Duration) = 0 THEN 
    RETURN StartDate; 
    END IF; 

    IF Timezone IS NOT NULL THEN SET StartDate = CONVERT_TZ(StartDate, 'UTC', Timezone); END IF; 

    IF Duration REGEXP '^P[0-9]+W$' THEN 
    SET StartDate = DATE_ADD(StartDate, INTERVAL SUBSTR(Duration, 2, LENGTH(Duration) - 2) WEEK); 
    RETURN IF(Timezone IS NULL, StartDate, CONVERT_TZ(StartDate, Timezone, 'UTC')); 
    END IF; 

    IF Duration NOT REGEXP '^P([0-9]+Y)?([0-9]+M)?([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+S)?)?$' THEN 
    RETURN NULL; 
    END IF; 

    SET Pos = LOCATE('T', Duration); 
    IF Pos <> 0 THEN 
    SET TimeStr = SUBSTR(Duration, Pos + 1); 
    SET Duration = SUBSTR(Duration, 2, Pos); 
    ELSE 
    SET Duration = SUBSTR(Duration, 2); 
    END IF ; 

    SET Pos = LOCATE('Y', Duration); 
    IF Pos <> 0 THEN 
    SET StartDate = DATE_ADD(StartDate, INTERVAL SUBSTR(Duration, 1, Pos - 1) YEAR); 
    SET Duration = SUBSTR(Duration, Pos + 1); 
    END IF; 

    SET Pos = LOCATE('M', Duration); 
    IF Pos <> 0 THEN 
    SET StartDate = DATE_ADD(StartDate, INTERVAL SUBSTR(Duration, 1, Pos - 1) MONTH); 
    SET Duration = SUBSTR(Duration, Pos + 1); 
    END IF; 

    SET Pos = LOCATE('D', Duration); 
    IF Pos <> 0 THEN 
    SET StartDate = DATE_ADD(StartDate, INTERVAL SUBSTR(Duration, 1, Pos - 1) DAY); 
    END IF; 

    IF LENGTH(TimeStr) <> 0 THEN 
    SET Pos = LOCATE('H', TimeStr); 
    IF Pos <> 0 THEN 
     SET StartDate = DATE_ADD(StartDate, INTERVAL SUBSTR(TimeStr, 1, Pos - 1) HOUR); 
     SET TimeStr = SUBSTR(TimeStr, Pos + 1); 
    END IF; 

    SET Pos = LOCATE('M', TimeStr); 
    IF Pos <> 0 THEN 
     SET StartDate = DATE_ADD(StartDate, INTERVAL SUBSTR(TimeStr, 1, Pos - 1) MINUTE); 
     SET TimeStr = SUBSTR(TimeStr, Pos + 1); 
    END IF; 

    SET Pos = LOCATE('S', TimeStr); 
    IF Pos <> 0 THEN 
     SET StartDate = DATE_ADD(StartDate, INTERVAL SUBSTR(TimeStr, 1, Pos - 1) SECOND); 
     SET TimeStr = SUBSTR(TimeStr, Pos + 1); 
    END IF; 
    END IF ; 

    RETURN IF(Timezone IS NULL, StartDate, CONVERT_TZ(StartDate, Timezone, 'UTC')); 
END $$ 
관련 문제