cálculos de data com sqlite3
-
19-09-2019 - |
Pergunta
Eu estou tentando calcular TimeSpans entre as datas. Não tenho nenhum problema com isso, se a data é formatado usando o formato sqlite3 nativa 'AAAA-dd-mm'
Como eu poderia fazer isso se a data é formatado de forma diferente, como 'dd-mm-AAAA'
Eu tentei o seguinte sem sucesso.
- Selecionar dias entre dois dias; Isso funciona se a seqüência de data e hora é formatada AAAA-dd-mm
SELECT julianday(date1) - julianday(date2) AS Span from myTable;
- Eu tentei isso para datas no formato dd-mm-AAAA mas doens't parecem funcionar --É parece ser que um formato de data não pode ser especificado.
SELECT julianday(strftime('%d-%m-%Y', date1)) - julianday(strftime('%d-%m-%Y', date2)) AS Span from myTable;
Solução
Uma vez que você estiver usando System.Data.SQLite eu recomendo usar uma função personalizada. Isso será mais fácil de usar e ser consistente com MS SQL Server, tornando-se mais claro para outros desenvolvedores .NET para entender e manter.
/// <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);
}
}
}