Convert SQL query to C# (SQL query converts base36 code to DateTime)
Convert SQL query to C# (SQL query converts base36 code to DateTime)
我希望能够在 7 位 \base36 配置中编码\解码包含日期时间的 ID,但是尽管有一个 SQL 查询来解码 ID,但到目前为止还没有成功。
我有一个 SQL 查询可以将代码转换为日期时间。
使用以下id,我希望得到相应的日期时间。
id Date Time
------------------------------------
A7LXZMM 2004-02-02 09:34:47.000
KWZKXEX 2018-11-09 11:15:46.000
LIZTMR9 2019-09-13 11:49:46.000
查询:
DECLARE @xdate DATETIME, @offset INT
DECLARE @recid VARCHAR(20)
SET @recid = 'KWZKXEX'
SET @offset = (SELECT DATEDIFF(ss, GETUTCDATE(), GETDATE())) /************* Number of hours offset from GMT ************/
SELECT
DATEADD(ss, @offset +
(POWER(CAST(36 AS BIGINT), 6) *
CASE
WHEN (SELECT ISNUMERIC(SUBSTRING(@recid, 1, 1))) = 0
THEN (SELECT ASCII(SUBSTRING(@recid, 1, 1))) - 55
ELSE (SELECT ASCII(SUBSTRING(@recid, 1, 1))) - 48
END +
POWER(CAST(36 AS BIGINT), 5) *
case
when(select isnumeric(substring(@recid,2,1))) = 0
then(select ascii(substring(@recid,2,1))) - 55
else (select ascii(substring(@recid,2,1))) - 48
End
+
POWER(cast(36 as bigint),4) *
case
when(select isnumeric(substring(@recid,3,1))) = 0
then(select ascii(substring(@recid,3,1))) - 55
else (select ascii(substring(@recid,3,1))) - 48
End
+
POWER(cast(36 as bigint),3) *
case
when(select isnumeric(substring(@recid,4,1))) = 0
then(select ascii(substring(@recid,4,1))) - 55
else (select ascii(substring(@recid,4,1))) - 48
End
+
POWER(cast(36 as bigint),2) *
case
when(select isnumeric(substring(@recid,5,1))) = 0
then(select ascii(substring(@recid,5,1))) - 55
else (select ascii(substring(@recid,5,1))) - 48
End
+
POWER(cast(36 as bigint),1) *
case
when(select isnumeric(substring(@recid,6,1))) = 0
then(select ascii(substring(@recid,6,1))) - 55
else (select ascii(substring(@recid,6,1))) - 48
End
+
POWER(cast(36 as bigint),0) *
case
when(select isnumeric(substring(@recid,7,1))) = 0
then(select ascii(substring(@recid,7,1))) - 55
else (select ascii(substring(@recid,7,1))) - 48
End
)
/50
,'1/1/1990')
using System;
using System.Globalization;
using System.Text;
using System.Numerics;
public class Program
{
public static void Main()
{
string sRecid = "A7LXZMM";
char c0 = sRecid[0];
char c1 = sRecid[1];
char c2 = sRecid[2];
char c3 = sRecid[3];
char c4 = sRecid[4];
char c5 = sRecid[5];
char c6 = sRecid[6];
double d6, d5, d4, d3, d2, d1, d0, dsecs;
Console.WriteLine("c0 = " + c0.ToString());
Console.WriteLine();
d6 = Math.Pow(36, 6) * ((Char.IsNumber(c0)) ? (byte)c0 - 55 : (byte)c0 - 48);
d5 = Math.Pow(36, 5) * ((Char.IsNumber(c1)) ? (byte)c1 - 55 : (byte)c1 - 48);
d4 = Math.Pow(36, 4) * ((Char.IsNumber(c2)) ? (byte)c2 - 55 : (byte)c2 - 48);
d3 = Math.Pow(36, 3) * ((Char.IsNumber(c3)) ? (byte)c3 - 55 : (byte)c3 - 48);
d2 = Math.Pow(36, 2) * ((Char.IsNumber(c4)) ? (byte)c4 - 55 : (byte)c4 - 48);
d1 = Math.Pow(36, 1) * ((Char.IsNumber(c5)) ? (byte)c5 - 55 : (byte)c5 - 48);
d0 = Math.Pow(36, 0) * ((Char.IsNumber(c6)) ? (byte)c6 - 55 : (byte)c6 - 48);
dsecs = d6 + d5 + d4 + d3 + d2 + d1 + d0 / 50;
DateTime dt = new DateTime(1990, 1, 1, 0, 0, 0,0, System.DateTimeKind.Utc);
dt = dt.AddSeconds( dsecs ).ToLocalTime();
Console.WriteLine("d6 = " + d6.ToString());
Console.WriteLine("d5 = " + d5.ToString());
Console.WriteLine("d4 = " + d4.ToString());
Console.WriteLine("d3 = " + d3.ToString());
Console.WriteLine("d2 = " + d2.ToString());
Console.WriteLine("d1 = " + d1.ToString());
Console.WriteLine("d0 = " + d0.ToString());
Console.WriteLine("dsecs = " + dsecs.ToString());
Console.WriteLine("dt = " + dt.ToString());
}
}
当我在 SQL 中使用以下 ID 时,我得到以下日期。
id Date Time
------------------------------------
A7LXZMM 2004-02-02 09:34:47.000
KWZKXEX 2018-11-09 11:15:46.000
LIZTMR9 2019-09-13 11:49:46.000
不幸的是,我的 C# "conversion" 非常不准确。
对我哪里出错有什么建议吗?
与 SQL 脚本相比,您的 C# 代码中的 Char.IsNumber
... 检查翻转了。
在您的 SQL 中,如果字符 不是 数字,您将减去 55
,否则将减去 48
。
在您的 C# 代码中,如果字符 是 数字,则减去 55
,否则减去 48
。
我认为您也没有正确计算 dsecs
。您需要添加 d6
到 d0
,然后除以 50
。按照您现在的方式,您将 d0
除以 50
,然后添加所有其他 dn
变量。
换句话说...
dsecs = d6 + d5 + d4 + d3 + d2 + d1 + d0 / 50;
应该是
dsecs = (d6 + d5 + d4 + d3 + d2 + d1 + d0) / 50;
我希望能够在 7 位 \base36 配置中编码\解码包含日期时间的 ID,但是尽管有一个 SQL 查询来解码 ID,但到目前为止还没有成功。
我有一个 SQL 查询可以将代码转换为日期时间。
使用以下id,我希望得到相应的日期时间。
id Date Time
------------------------------------
A7LXZMM 2004-02-02 09:34:47.000
KWZKXEX 2018-11-09 11:15:46.000
LIZTMR9 2019-09-13 11:49:46.000
查询:
DECLARE @xdate DATETIME, @offset INT
DECLARE @recid VARCHAR(20)
SET @recid = 'KWZKXEX'
SET @offset = (SELECT DATEDIFF(ss, GETUTCDATE(), GETDATE())) /************* Number of hours offset from GMT ************/
SELECT
DATEADD(ss, @offset +
(POWER(CAST(36 AS BIGINT), 6) *
CASE
WHEN (SELECT ISNUMERIC(SUBSTRING(@recid, 1, 1))) = 0
THEN (SELECT ASCII(SUBSTRING(@recid, 1, 1))) - 55
ELSE (SELECT ASCII(SUBSTRING(@recid, 1, 1))) - 48
END +
POWER(CAST(36 AS BIGINT), 5) *
case
when(select isnumeric(substring(@recid,2,1))) = 0
then(select ascii(substring(@recid,2,1))) - 55
else (select ascii(substring(@recid,2,1))) - 48
End
+
POWER(cast(36 as bigint),4) *
case
when(select isnumeric(substring(@recid,3,1))) = 0
then(select ascii(substring(@recid,3,1))) - 55
else (select ascii(substring(@recid,3,1))) - 48
End
+
POWER(cast(36 as bigint),3) *
case
when(select isnumeric(substring(@recid,4,1))) = 0
then(select ascii(substring(@recid,4,1))) - 55
else (select ascii(substring(@recid,4,1))) - 48
End
+
POWER(cast(36 as bigint),2) *
case
when(select isnumeric(substring(@recid,5,1))) = 0
then(select ascii(substring(@recid,5,1))) - 55
else (select ascii(substring(@recid,5,1))) - 48
End
+
POWER(cast(36 as bigint),1) *
case
when(select isnumeric(substring(@recid,6,1))) = 0
then(select ascii(substring(@recid,6,1))) - 55
else (select ascii(substring(@recid,6,1))) - 48
End
+
POWER(cast(36 as bigint),0) *
case
when(select isnumeric(substring(@recid,7,1))) = 0
then(select ascii(substring(@recid,7,1))) - 55
else (select ascii(substring(@recid,7,1))) - 48
End
)
/50
,'1/1/1990')
using System;
using System.Globalization;
using System.Text;
using System.Numerics;
public class Program
{
public static void Main()
{
string sRecid = "A7LXZMM";
char c0 = sRecid[0];
char c1 = sRecid[1];
char c2 = sRecid[2];
char c3 = sRecid[3];
char c4 = sRecid[4];
char c5 = sRecid[5];
char c6 = sRecid[6];
double d6, d5, d4, d3, d2, d1, d0, dsecs;
Console.WriteLine("c0 = " + c0.ToString());
Console.WriteLine();
d6 = Math.Pow(36, 6) * ((Char.IsNumber(c0)) ? (byte)c0 - 55 : (byte)c0 - 48);
d5 = Math.Pow(36, 5) * ((Char.IsNumber(c1)) ? (byte)c1 - 55 : (byte)c1 - 48);
d4 = Math.Pow(36, 4) * ((Char.IsNumber(c2)) ? (byte)c2 - 55 : (byte)c2 - 48);
d3 = Math.Pow(36, 3) * ((Char.IsNumber(c3)) ? (byte)c3 - 55 : (byte)c3 - 48);
d2 = Math.Pow(36, 2) * ((Char.IsNumber(c4)) ? (byte)c4 - 55 : (byte)c4 - 48);
d1 = Math.Pow(36, 1) * ((Char.IsNumber(c5)) ? (byte)c5 - 55 : (byte)c5 - 48);
d0 = Math.Pow(36, 0) * ((Char.IsNumber(c6)) ? (byte)c6 - 55 : (byte)c6 - 48);
dsecs = d6 + d5 + d4 + d3 + d2 + d1 + d0 / 50;
DateTime dt = new DateTime(1990, 1, 1, 0, 0, 0,0, System.DateTimeKind.Utc);
dt = dt.AddSeconds( dsecs ).ToLocalTime();
Console.WriteLine("d6 = " + d6.ToString());
Console.WriteLine("d5 = " + d5.ToString());
Console.WriteLine("d4 = " + d4.ToString());
Console.WriteLine("d3 = " + d3.ToString());
Console.WriteLine("d2 = " + d2.ToString());
Console.WriteLine("d1 = " + d1.ToString());
Console.WriteLine("d0 = " + d0.ToString());
Console.WriteLine("dsecs = " + dsecs.ToString());
Console.WriteLine("dt = " + dt.ToString());
}
}
当我在 SQL 中使用以下 ID 时,我得到以下日期。
id Date Time
------------------------------------
A7LXZMM 2004-02-02 09:34:47.000
KWZKXEX 2018-11-09 11:15:46.000
LIZTMR9 2019-09-13 11:49:46.000
不幸的是,我的 C# "conversion" 非常不准确。
对我哪里出错有什么建议吗?
与 SQL 脚本相比,您的 C# 代码中的 Char.IsNumber
... 检查翻转了。
在您的 SQL 中,如果字符 不是 数字,您将减去 55
,否则将减去 48
。
在您的 C# 代码中,如果字符 是 数字,则减去 55
,否则减去 48
。
我认为您也没有正确计算 dsecs
。您需要添加 d6
到 d0
,然后除以 50
。按照您现在的方式,您将 d0
除以 50
,然后添加所有其他 dn
变量。
换句话说...
dsecs = d6 + d5 + d4 + d3 + d2 + d1 + d0 / 50;
应该是
dsecs = (d6 + d5 + d4 + d3 + d2 + d1 + d0) / 50;