PHP 毫秒级时间戳生成
做消息队列时发现在 Redis 的 ZSet 中,Score 数字只能设置到 17 位,我想让 Score 唯一,就尝试了几种时间戳 + 随机数的组合,于是得出一些答案
代码如下:
/*** 取毫秒级时间戳,默认返回普通秒级时间戳 time() 及 3 位长度毫秒字符串** @param int $msec_length 毫秒长度,默认 3* @param int $random_length 添加随机数长度,默认 0* @param bool $dot 随机是否存入小数点,默认 false* @param int $delay 是否延迟,传入延迟秒数,默认 0* @return string*/
function msectime($msec_length = 3, $random_length = 0, $dot = false, $delay = 0) {list($msec, $sec) = explode(' ', microtime());$rand = $random_length > 0 ?number_format(mt_rand(1, (int)str_repeat('9', $random_length))* (float)('0.' . str_repeat('0', $random_length - 1) . '1'),$random_length,'.','') : '';$msectime = sprintf('%.0f', (floatval($msec) + floatval($sec) + $delay) * pow(10, $msec_length));return $dot ? $msectime . '.' . substr($rand, 2) : $msectime . substr($rand, 2);
}
假设此刻调用上面的方法 msectime(7)
得到 15283761526669518
然后把这个数字扔进 Redis ZSet 的 Score 里,如下图,是正常的:
但是我们加一位,例如,变成了 152837615266695181
哦豁,变成了科学计数?Emmm,显然不合情理,这玩意儿似乎会丢掉精度呢。
怎么办?既然只能 17 位,我们就考虑减少时间戳的位数,当然毫秒级时间戳是非常精确的,先来看几个效果:
保留 3 位毫秒,即 10 位秒级时间戳 + 3 位毫秒。
for ($i = 0; $i < 100; $i++) {echo msectime() . '<br>';
}
结果如下:(长图慎入)
看起来有点意思,但是注意屁股 3 位数,这循环 100 次的结果,大部分数据都是一样的,当然这种情况,我们可以考虑在后面直接 mt_rand()
生成 5 4 位随机数拼接上
我考虑了一下这个,还是觉得不太保险,继续尝试加长毫秒位数,直接加两位看看
5 位毫秒
for ($i = 0; $i < 100; $i++) {echo msectime(5) . '<br>';
}
结果如下:
结果很好了!屁股两位的重复率很低!此时的数字长度为 15 位,似乎再生成两位随机数就可以了?
当然常规的随机数生成会考虑 mt_rand(10, 99)
这种形式
我建议这样生成:
function ex_mt_rand($length) {$result = '';for ($i = 0; $i < $length; $i++) {$result .= mt_rand(0, 9);}return $result;
}
这样能得到更广的随机结果值,相比起普通的 mt_rand()
更可靠一些。
例如我们生成验证码之类,结果图参考:
回到正题!既然也存在小部分重复值的情况,在我看来依靠随机数总是有风险的(当然没有位数限制,完全可以考虑扩大随机范围)
于是我直接把毫秒时间戳扩大到 17 位再看
7 位毫秒
for ($i = 0; $i < 100; $i++) {echo msectime(7) . '<br>';
}
惊喜的发现!完全没有重复值了,当然 Redis 里的 Score 长度被用光了,无法再随机哪怕 1 位数字
不过这个我的需求已经满足了!
以上方法是本人根据实际需求所写的一个,通过这个思路我们可以利用毫秒级时间戳生成订单号等需求。
再写一个例子:
msectime(3, 5, true);// 得到结果如下
1528377789213.17053
1528377789213.19110
1528377789213.80717
1528377789213.12004
1528377789214.91335
1528377789214.08298
1528377789214.92701
1528377789214.85589
1528377789214.62383
欢迎大神提供更好的思路在秒杀等情况下生成不重复的数值。
PHP 毫秒级时间戳生成相关推荐
- python毫秒级时间戳
import datetime print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')) print(datetime.d ...
- Python 技术篇-使用time库获取秒级时间戳、毫秒级时间戳实例演示
time.time() 可以获取时间戳. 秒级时间戳就是把它的小数部分四舍五入去掉,转化成整数. 毫秒级时间戳就是取小数点后的四位,四舍五入一下. import timetime_stamp = ti ...
- python获取时间秒数_Python获取秒级时间戳与毫秒级时间戳
1.获取秒级时间戳与毫秒级时间戳.微秒级时间戳 import time import datetime t = time.time() print (t) #原始时间数据 print (int(t)) ...
- python获取时间戳毫秒级_Python获取秒级时间戳与毫秒级时间戳
1.获取秒级时间戳与毫秒级时间戳.微秒级时间戳 import time import datetime t = time.time() print (t) #原始时间数据 print (int(t)) ...
- Linux 获取毫秒级时间戳
Linux 获取毫秒级时间戳 在Linux中获取ms级别的时间戳,需要结合gettimeofday()以及localtime()函数.如下所示: #include <time.h> # ...
- MySQL 获取当前时间的秒级、毫秒级时间戳
# 秒级时间戳:1606371113 UNIX_TIMESTAMP(NOW()) # 毫秒级时间戳:1606371209293 REPLACE(unix_timestamp(current_times ...
- Python获取秒级时间戳与毫秒级时间戳
协调世界时 又称世界统一时间.世界标准时间.国际协调时间,简称UTC. 在计算机中,时间实际上是用数字表示的.我们把1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch t ...
- 毫秒级时间戳获取与使用
获取毫秒级时间戳 public function aaa(){$mill_time=microtime();$timeInfo = explode(' ', $mill_time);$milis_ti ...
- C#时间戳计算公式、毫秒级时间戳
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数. 时间戳转换的网址一大把,百度随便搜一下就有,比如: http:// ...
最新文章
- java的printf语法_java printf的一些常用的打印格式总结
- 2021年中国自有品牌行业发展白皮书
- 【Flink】Apache Flink 1.13.0 正式发布,流处理应用更加简单高效
- python爬虫定时运行_python 每天如何定时启动爬虫任务
- qtcpsocket断开_Qt QTcpSocket 对连接服务器中断的不同情况进行判定
- 【WordPress】添加备案信息
- sap crm button_如何安装SAP软件?
- jquery解绑、绑定笔记
- 功能性测试用例设计方法深入理解
- 如何选择企业电脑加密软件,知道这几点一定不后悔!
- freemarker遍历list处理第一个、最后一个元素
- python识图找图_【python 图像识别】图像识别从菜鸟
- 智慧医院从建设智慧病房开始
- Scrapy爬虫实践之搜索并获取前程无忧职位信息(基础篇)
- CodeGear RAD Studio 2009 update1 下载地址
- 关于Apache服务器配置SSL证书的那些事(保姆级教程)
- 【分享】高精度RTK定位解决方案
- 移动APP对我们的生活影响?
- 1.DevOps简介
- The Coder Vol.8:算法的心机