Расчет даты с помощью sqlite3

Я пытаюсь рассчитать TimeSpans между датами. У меня нет проблем с этим, если дата отформатирована с использованием собственного формата sqlite3 'ГГГГ-дд-мм'

Как бы это сделать, если дата отформатирована по-другому, например «дд-мм-ГГГГ»

Я безуспешно пробовал следующее.

--Выберите дни между двумя днями; это работает, если строка datetime сформирована YYYY-dd-mm

SELECT julianday(date1) - julianday(date2) AS Span from myTable;

- Я пробовал это для дат в формате дд-мм-ГГГГ, но, похоже, это не работает. - Похоже, что формат даты не может быть указан.

SELECT julianday(strftime('%d-%m-%Y', date1)) - julianday(strftime('%d-%m-%Y', date2)) AS Span from myTable;

person galford13x    schedule 12.03.2010    source источник


Ответы (1)


Поскольку вы используете System.Data.SQLite, я бы рекомендовал использовать настраиваемую функцию. Это будет проще в использовании и будет согласовано с MS SQL Server, что сделает его более понятным и понятным для других разработчиков .NET.

/// <summary>
/// MS SQL 2005 Compatible DateDiff() function.
/// </summary>
/// <remarks>
/// ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.SQL.v2005.en/tsqlref9/html/eba979f2-1a8d-4cce-9d75-b74f9b519b37.htm
/// 
/// 
/// </remarks>
[SQLiteFunction(Name = "DateDiff", Arguments = 3, FuncType = FunctionType.Scalar)]
public class DateDiff : SQLiteFunction
{
    public override object Invoke(object[] args)
    {
        if (args[0] == DBNull.Value || 
            args[1] == DBNull.Value ||
            args[2] == DBNull.Value)
        {
            return null;
        }
        string part = Convert.ToString(args[0]);
        DateTime startTime = ToDateTime(args[1]);
        DateTime endTime = ToDateTime(args[2]);

        switch(part)
        {
            case "year":
            case "yy":
            case "yyyy":
                return endTime.Year - startTime.Year;

            case "quarter":
            case "qq":
            case "q":
                return (endTime.Year - startTime.Year) * 4 + ((endTime.Month - 1) / 3) - ((startTime.Month - 1) / 3);

            case "month":
            case "mm":
            case "m":
                return (endTime.Year - startTime.Year) * 12 + endTime.Month - startTime.Month;

            case "dayofyear":
            case "dy":
            case "y":
            case "day":
            case "dd":
            case "d":
                return (endTime - startTime).TotalDays;

            case "week":
            case "wk":
            case "ww":
                return (endTime - startTime).TotalDays / 7.0;

            case "Hour":
            case "hh":
            case "h":
                return (endTime - startTime).TotalHours;

            case "minute":
            case "mi":
            case "n":
                return (endTime - startTime).TotalMinutes;

            case "second":
            case "ss":
            case "s":
                return (endTime - startTime).TotalSeconds;

            case "millisecond":
            case "ms":
                return (endTime - startTime).TotalMilliseconds;

            default:
                throw new ArgumentException(String.Format("Date part '{0}' is not recognized.", part));
        }

    }

    private static DateTime ToDateTime(object source)
    {
        try
        {
            return Convert.ToDateTime(source);              
        } 
        catch (Exception ex)
        {
            throw new ArgumentException(String.Format("DateDiff Input value '{0}' can not be converted to a DateTime.", source), ex);
        }
    }
}
person Samuel Neff    schedule 12.03.2010
comment
В итоге я решил проблему, экспортировав таблицу, изменив формат столбца даты на собственный формат sqlite3, а затем повторно импортировав таблицу. Однако мне нравится этот метод, и я думаю реализовать и протестировать его. Я вернусь с результатами. - person galford13x; 15.03.2010
comment
К сожалению, кажется, что для того, чтобы это сработало, вам нужно передать первый параметр в виде строки. например: dateiff ('mi', date2, date1), но в SQL Server вам нужно передать его без кавычек, например, dateiff (mi, date2, date1) - person NYCChris; 21.12.2011
comment
@NYCChris, хороший момент, эта версия для SQLite использует строки, а функции MSSQL используют константы datepart. Я не знаю, как воспроизвести константы в SQLite. - person Samuel Neff; 21.12.2011