Как преобразовать формат session_time SCORM 2004 в удобный формат даты и времени в SQL

Таким образом, формат session_time в SCORM 2004 выглядит следующим образом.

P[yY][mM][dD][T[hH][mM][s[.s]S]]

Если параметры в квадратных скобках являются необязательными, однако он должен включать по крайней мере 1 из параметров.

Пример формата PT0H0M47S

Что означает 0 часов, 0 минут и 47 секунд.

Значение хранится как varchar в базе данных MSSQL.

Мне нужно иметь возможность преобразовать этот строковый формат в пригодный для использования формат, чтобы я мог добавить это время к дате начала, чтобы определить время окончания.

В настоящее время я перемещаю данные SCORM из старой базы данных в новую 1. Я мог бы сделать это на PHP и легко отформатировать время, но я бы предпочел написать все сценарии импорта на SQL.

Любая помощь по этому вопросу будет принята с благодарностью.

РЕДАКТИРОВАТЬ:

Если это поможет, это функция PHP, которую я написал для обработки формата для другой цели.

private function formatDuration($duration)
{
    $count = preg_match('/P(([0-9]+)Y)?(([0-9]+)M)?(([0-9]+)D)?T?(([0-9]+)H)?(([0-9]+)M)?(([0-9]+)(\.[0-9]+)?S)?/', $duration, $matches);

    if ($count)
    {
        $_years = (int) $matches[2];
        $_months = (int) $matches[4];
        $_days = (int) $matches[6];
        $_hours = (int) $matches[8];
        $_minutes = (int) $matches[10];
        $_seconds = (int) $matches[12];
    }
    else
    {
        if (strstr($duration, ':'))
        {
            list($_hours, $_minutes, $_seconds) = explode(':', $duration);
        }
        else
        {
            $_hours = 0;
            $_minutes = 0;
            $_seconds = 0;
        }
    }

    // I just ignore years, months and days as it is unlikely that a
    // course would take any longer than 1 hour
    return $_seconds + (($_minutes + ($_hours * 60)) * 60);
}

person MajorCaiger    schedule 08.08.2013    source источник


Ответы (2)


Просто разработал решение для меня.

Это нужно было бы поместить в функцию SQL для меня, и мне нужно было бы закончить последний бит, где я решаю, какой формат я хочу.

Я обновляю только около 900 строк, и это однократное обновление, поэтому производительность не является проблемой.

DECLARE @session_time varchar(200) = 'P50Y2M3DT4H5M6S'

DECLARE @date varchar(100) = ''
DECLARE @time varchar(100) = ''

DECLARE @year varchar(20) = '0'
DECLARE @month varchar(20) = '0'
DECLARE @day varchar(20) = '0'
DECLARE @hour varchar(20) = '0'
DECLARE @minute varchar(20) = '0'
DECLARE @second varchar(20) = '0'

-- Remove the P
SET @session_time = SUBSTRING(@session_time, 2, LEN(@session_time)-1)

-- If we have a T
IF PATINDEX('%T%',@session_time) > 0
BEGIN
    SET @date = SUBSTRING(@session_time, 0, PATINDEX('%T%',@session_time))

    SET @time = SUBSTRING(@session_time, LEN(@date + 'T') + 1, LEN(@session_time))
END
ELSE
BEGIN
    SET @time = @session_time;
END

-- Get the date parts
IF LEN(@date) > 0
BEGIN
    -- If theres a year
    IF PATINDEX('%Y%',@date) > 0
    BEGIN
        SET @year = SUBSTRING(@date, 0, PATINDEX('%Y%',@date))

        SET @date = SUBSTRING(@date, LEN(@year + 'Y') + 1, LEN(@date))
    END

    -- If theres a month
    IF PATINDEX('%M%',@date) > 0
    BEGIN
        SET @month = SUBSTRING(@date, 0, PATINDEX('%M%',@date))

        SET @date = SUBSTRING(@date, LEN(@month + 'M') + 1, LEN(@date))
    END

    -- If theres a day
    IF PATINDEX('%D%',@date) > 0
    BEGIN
        SET @day = SUBSTRING(@date, 0, PATINDEX('%D%',@date))

        SET @date = SUBSTRING(@date, LEN(@day + 'D') + 1, LEN(@date))
    END
END

-- Get the time parts
IF LEN(@time) > 0
BEGIN
    -- If theres an hour
    IF PATINDEX('%H%',@time) > 0
    BEGIN
        SET @hour = SUBSTRING(@time, 0, PATINDEX('%H%',@time))

        SET @time = SUBSTRING(@time, LEN(@hour + 'H') + 1, LEN(@time))
    END

    -- If theres a minute
    IF PATINDEX('%M%',@time) > 0
    BEGIN
        SET @minute = SUBSTRING(@time, 0, PATINDEX('%M%',@time))

        SET @time = SUBSTRING(@time, LEN(@minute + 'M') + 1, LEN(@time))
    END

    -- If theres a second
    IF PATINDEX('%S%',@time) > 0
    BEGIN
        SET @second = SUBSTRING(@time, 0, PATINDEX('%S%',@time))

        SET @time = SUBSTRING(@time, LEN(@second + 'S') + 1, LEN(@time))
    END
END

PRINT @year + ' years '
PRINT @month + ' months '
PRINT @day + ' days '
PRINT @hour + ' hours '
PRINT @minute + ' minutes '
PRINT @second + ' seconds '
person MajorCaiger    schedule 08.08.2013

Мое решение:

PTMHStoHHMMSS : function(val){ //custom SCORM extension to convert P[yY][mM][dD][T[hH][mM][s[.s]S]] to hh:mm:ss
        var seconds, minutes, hours;

        hours  = val.match(/(?:T)(.*)(?:[H])/i); //match everything between T & H
        if (hours.length > 0){
            hours = hours[1] * 1;
        } else {
            hours = 0;
        }

        minutes  = val.match(/(?:T.*[H])(.*)(?:[M])/i); //match everything between H & M that's after T
        if (minutes.length > 0){
            minutes = minutes[1] * 1;
        } else {
            minutes = 0;
        }

        seconds  = val.match(/(?:T.*[M])(.*)(?:[S])/i); //match everything between M & S that's after T
        if (seconds.length > 0){
            seconds = seconds[1] * 1;
        } else {
            seconds = 0;
        }
        //pad lower number with 0 if needed
        if (hours   < 10){ hours   = "0" + hours;   }
        if (minutes < 10){ minutes = "0" + minutes; }
        if (seconds < 10){ seconds = "0" + seconds; }
    return hours + ':' + minutes + ':' + seconds;
    }
person user3638793    schedule 25.01.2019