时间:2011-03-23 13:06:56

标签: algorithm

采用包含年,月,日,小时,分钟,秒的时间戳并将其转换为7位数或更少(但一致的)字母数字表示的优秀算法。 字母数字表示不会区分大写和小写字母。

3 个答案:

答案 0 :(得分:12)

让我们做一些数学

您可以使用7个字母数字。每个字母数字数字取36个可能的不同值(26个字母,10个十进制数字)中的值 所以我们有36 ^ 7个不同的值,即78364164096。

现在我们计算表示一年中给定时间戳所需的不同值的数量。 为了简化一些事情,我们将允许一些永远不会发生的值(例如:11月31日)。

因此,我们有

month: 12  -> coded from 0 to 11
day: 31  -> coded from 0 to 30
hour: 24
minute: 60
second: 60 

使用32140800不同的可能性

我们现在划分为78364164096/32140800,即~2438,因此我们将列出从00:00 1 0000到23:59 dec 31 2437的时间戳。

然后编码

X = second + minute*60 + hour*60*60 + 
    day*60*60*24 + month*60*60*24*31 + 
    year*60*60*24*31*12

解码是

second = X mod 60
minute = (X div 60) mod 60
hour = (X div 60*60) mod 24
day = (X div 60*60*24) mod 31
month = (X div 60*60*24*31) mod 12
year = X div 60*60*24*31*12

让我们看一个例子:

假设您要编码日期12月20日,1998年05:33:12 所以你会有

second: 12
minute: 33
hour: 5
day: 19   -> note that we encode days in the range 0..31
month: 11  -> note that we conde months in the range 0..11
year: 1998

所以我们计算:

X = 12 + 33*60 + 5*60*60 + 
        19*60*60*24 + 11*60*60*24*31 + 
        1998*60*60*24*31*12

即X = 12 + 1980 + 18000 + 1641600 + 29462400 + 64217318400 = 64248442392

现在我们解码了

second = 64248442392 mod 60  = 12
minute = (64248442392 div 60) mod 60 = 33
hour = (64248442392 div 60*60) mod 24 = 5
day = (64248442392 div 60*60*24) mod 31 = 19
month = (64248442392 div 60*60*24*31) mod 12 = 11
year = 64248442392 div 60*60*24*31*12 = 1998

答案 1 :(得分:0)

我编写了将整数编码为短字符串的代码,以及我对a previous question的回答中的一些注意事项。

您仍然需要决定如何将日期时间映射到整数,但其他答案已经解决了这个问题。

答案 2 :(得分:0)

考虑高于十进制的数字系统。例如,十六进制数字系统是base-16。让我们说在我们的新数字系统中,我们有数字0-9,小写字母(a-z)和大写字母(A-Z)。这给了我们62个可能的数字,所以我们可以使用base-62数字系统。这是一些用于转换的Javascript代码 -

charRange

digits只是一个实用程序箭头函数,用于从ASCII代码

创建一系列字符

base表示数字系统中的所有有效数字。您可以在此列表中添加更多有效数字(如特殊字符)

{{1}}是可用数字的数字(十进制)

在这个base-62数字系统中编码的输出将保持6位数长,超过1,700年。

编辑:已实现Date.now()以毫秒为单位返回时间戳而不是秒,所以我更新了我的答案以反映