设为首页收藏本站淘宝杂货铺

从F到0 - From F to 0

 找回密码
 注册已关闭
搜索
查看: 5370|回复: 4
收起左侧

[PHP/ASP/JSP] 64位新款毫秒时间戳计时转换公式算法PHP7实现 带时区星期功能 0年1月1日开始

[复制链接]
发表于 2019-2-13 23:17:32 | 显示全部楼层 |阅读模式
  1. <?php

  2. /*

  3. 64位时间戳计时转换公式PHP7算法 带时区星期毫秒。
  4. 本程序为64位PHP7.3.1环境编写,低于该版本可能会出现语法解析错误,不支持32位PHP。
  5. 本算法计算0年1月1日0时0分0秒与指定日期所经历的毫秒数,存在bug楼下回复。

  6. */


  7. define('OYM',[31,28,31,30,31,30,31,31,30,31,30,31]);                //平年月份表
  8. define('LYM',[31,29,31,30,31,30,31,31,30,31,30,31]);                //闰年月份表
  9. define('OYW',[6,2,2,5,0,3,5,1,4,6,2,4]);                        //平年月代码(计算星期用)
  10. define('LYW',[5,1,2,5,0,3,5,1,4,6,2,4]);                        //闰年月代码
  11. define('ODD',[0,31,59,90,120,151,181,212,243,273,304,334]);        //平年某月1日与1月1日距离天数
  12. define('LDD',[0,31,60,91,121,152,182,213,244,274,305,335]);        //闰年某月1日与1月1日距离天数
  13. define('UNIX_TIMESTAMP64',62167190400000);                        //1970年1月1日的64位时间戳(用于与Unix时间戳转换)

  14. define('TEXT_WEEK_CN',['星期日','星期一','星期二','星期三','星期四','星期五','星期六']);

  15. function his_to_sec($hour,$minute,$second){        //时分秒求1天中的多少秒 返回0~86399
  16.         return $hour * 3600 + $minute * 60 + $second;

  17. }
  18. function sec_to_his($sec,&$hour,&$minute,&$second){        //1天中的多少秒0~86399 求时分秒
  19.         $hour = floor($sec / 3600) %24;
  20.         $minute = floor($sec / 60) %60;
  21.         $second = $sec %60;
  22. }


  23. function is_leap_year($year){        //是否为闰年
  24.         return ($year %4 == 0 && $year %100 !=0 || $year % 400 == 0) ? 1 : 0;
  25. }

  26. function get_total_leap_year($year){        //计算指定年数有多少个闰年
  27.         return floor($year/4) - floor($year/100) + floor($year/400);
  28. }

  29. function get_year_total_day($year){        //计算指定年数有多少天(带闰年)
  30.         return $year * 365 + get_total_leap_year($year);
  31. }

  32. function get_1year_day($year){                 //取指定1年有多少天(平年返回365闰年366)
  33.         return is_leap_year($year) ? 366 : 365;
  34. }

  35. /*
  36. 已知月日获取1年中的第几天(平年最大返回365闰年最大366最小1)
  37. 参数1:月 参数2:日 参数3:平年0闰年1 (失败返回0)
  38. */
  39. function month_day_arrive_day($month,$day,$leap){        
  40.                 if(!is_ymdhis(!$leap,$month,$day)){
  41.                         return 0;
  42.                 }
  43.         return ($leap ? LDD[$month-1] : ODD[$month-1]) + $day;
  44. }

  45. /*
  46. 已知1年中的第几天获取几月几日
  47. 参数1:天数(平年最大返回365闰年最大366)
  48. 参数2、3:月、日(变量传出)
  49. 参数3:平年0闰年1 成功返回1失败返回0(失败不会改变变量)
  50. */

  51. function day_arrive_month_day($days,&$month,&$day,$leap){
  52.         if($days < 1 || $days > ($leap ? 366 : 365)) {
  53.                 return 0;
  54.         }
  55.         for($dec=12;$dec>0;$dec--){
  56.         $month_code = $leap ? LDD[$dec-1] : ODD[$dec-1];
  57.         if($days > $month_code){
  58.                 $month = $dec;
  59.                 $day = $days - $month_code;
  60.                 break;
  61.                         }
  62.                 }
  63.         return 1;
  64. }


  65. function get_year_first_week($year){        //获取指定年份1月1日是星期几 星期1为1 星期2为2 ... 星期日为0
  66.         return ((1+get_year_total_day($year)-get_1year_day($year))%7);
  67. }


  68. function get_year_month_have_day($year,$month){                //已知年月求该月有多少天(失败返回0)
  69.                 if($year < 0 || $month < 1 || $month > 12) {
  70.                         return 0;
  71.                 }
  72.         return is_leap_year($year) ? LYM[$month-1] : OYM[$month-1];
  73. }


  74. function is_ymdhis($year=0,$month,$day,$hour=0,$minute=0,$second=0,$millisecond=0){        //年月日是否有效
  75.         if($year < 0 || $month < 1 || $day < 1 || $hour < 0 || $minute < 0 || $second < 0 || $millisecond < 0){
  76.                 return 0;
  77.                 } elseif($hour > 23 || $minute > 59 || $second > 59 || $millisecond > 999 || $month > 12){
  78.                 return 0;
  79.                 }
  80.         return ($day <= get_year_month_have_day($year,$month)) ? 1 : 0;

  81. }

  82. function get_week($year,$month,$day){        //年月日取星期几 星期日为1 星期1为2 (失败返回0)
  83.                 if(!is_ymdhis($year,$month,$day)) {
  84.                         return 0;
  85.                 }

  86.         $leap = is_leap_year($year);
  87.         $first_week = get_year_first_week($year);
  88.         $year_code = $leap ? (($first_week+2)%7) : (($first_week+8)%7);
  89.         $month_code = $leap ? LYW[$month-1] :OYW[$month-1];
  90.         $week = ($year_code + $month_code + $day) % 7;
  91.                 if($week == 0) {
  92.                         $week = 7;
  93.                 }

  94.         return $week;
  95.                
  96. }

  97. function get_day_total_year($day){        //已知天数求出有多少年(含闰年)
  98.         $sday = $day;
  99.         $year400 = floor($sday / 146097);
  100.         $sday %= 146097;
  101.         $year100 = floor($sday / 36524);
  102.         $sday %= 36524;
  103.         $year4 = floor($sday / 1461);
  104.         $sday %= 1461;

  105.         if($sday <= 365){
  106.                 $year1=0;
  107.         } elseif($sday <= 730){
  108.                 $year1=1;
  109.         }elseif($sday <= 1095){
  110.                 $year1=2;

  111.         } else {
  112.                 $year1=3;
  113.         }

  114.         return $year1 + $year4*4 + $year100 * 100 + $year400 * 400;
  115. }


  116. function ymd_to_day($year,$month,$day){        //已知年月日计算与0年1月1日距离多少天
  117.         $leap = is_leap_year($year);
  118.         return month_day_arrive_day($month,$day,$leap) - $leap + get_year_total_day($year);

  119. }


  120. function day_to_ymd($days,&$year,&$month,&$day){         //计算0年1月1日的未来指定天数等于指定年月日(成功返回1失败0)
  121.         $year = get_day_total_year($days);
  122.                 if($year % 100 == 0){
  123.                         $year = get_day_total_year($days -1);
  124.                 }
  125.         $leap = is_leap_year($year);
  126.         $days -= get_year_total_day($year);

  127.         return day_arrive_month_day($days + $leap,$month,$day,$leap);
  128. }



  129. /*
  130. 64位时间戳编码 成功返回时间戳 失败或溢出返回 -1
  131. 参数1~7:年 月 日 时 分 秒 毫秒
  132. 参数8:时区(小数,默认为8)
  133. */

  134. function timestamp64_encode($year,$month,$day,$hour=0,$minute=0,$second=0,$millisecond=0,$time_zone=8){        
  135.         if(!is_ymdhis($year,$month,$day,$hour,$minute,$second,$millisecond)){
  136.                 return -1;
  137.         }
  138.         $return = his_to_sec($hour,$minute,$second) * 1000 + $millisecond;
  139.         $return = ymd_to_day($year,$month,$day) * 86400000 - $time_zone * 3600000 + $return;
  140.         if($return < 0) {
  141.                 return -1;
  142.         }
  143.                 return $return;

  144. }

  145. /*
  146. 64位时间戳解码 成功返回1,计算失败或溢出返回0 (如果返回0不要对传出的变量进行任何操作)
  147. 参数1:64位时间戳
  148. 参数2~9(必须为变量):年、月、日,星期、时、分、秒、毫秒。
  149. 参数10:时区(小数,默认为8)
  150. 其中星期日为1,星期一为2 (年、月、日为必须参数变量其余允许留空)
  151. */
  152. function timestamp64_decode($timestamp64,&$year,&$month,&$day,&$week =0,&$hour=0,&$minute=0,&$second=0,&$millisecond=0,$time_zone=8){
  153.         $timestamp64 = $timestamp64 + $time_zone * 3600000;
  154.                 if($timestamp64 < 0){
  155.                         return 0;
  156.                 }
  157.                 $millisecond = $timestamp64 % 1000;
  158.                 $timestamp64 = floor($timestamp64 / 1000);
  159.                
  160.                 sec_to_his($timestamp64 % 86400,$hour,$minute,$second);
  161.                 $timestamp64 = floor($timestamp64 / 86400);
  162.                 day_to_ymd($timestamp64,$year,$month,$day);
  163.                         if(!is_ymdhis($year,$month,$day,$hour,$minute,$second,$millisecond)){
  164.                                 return 0;
  165.                         }
  166.                 $week = get_week($year,$month,$day);
  167.                         return 1;
  168. }

  169. function timestamp64_to_unix($timestamp64){                //64位时间戳转Unix时间戳(不保留毫秒)
  170.         return floor($timestamp64/1000) - UNIX_TIMESTAMP64/1000;

  171. }

  172. function unix_to_timestamp64($unix){        //Unix时间戳转64位时间戳
  173.         return $unix * 1000 + UNIX_TIMESTAMP64;

  174. }


  175. function test(){ //以下函数用于测试,正式调用请删除


  176. $ms = microtime(1);
  177. $ms = floor(($ms - floor($ms))*1000);

  178. $timestamp64 = timestamp64_encode(date("Y"),date("m"),date("d"),date("H"),date("i"),date("s"),$ms);


  179. $unix1 = time();
  180. echo "64位时间戳:".$timestamp64."<br>";
  181. $unix2 = timestamp64_to_unix($timestamp64);

  182. echo "转换后Unix时间戳:".$unix2."<br>";
  183. echo "time函数取出Unix时间戳:".$unix1."<br>";

  184. timestamp64_decode($timestamp64,$y,$m,$d,$w,$h,$i,$s,$ms);

  185. $w = TEXT_WEEK_CN[$w-1];
  186. echo " {$y}年{$m}月{$d}日 {$w} {$h}时 {$i}分 {$s}秒 {$ms}毫秒";



  187. }
  188. test();



  189. ?>


复制代码

相关帖子

发表于 2019-2-15 18:23:09 | 显示全部楼层
[code=0]感谢楼主分享[/code]
发表于 2019-4-10 07:14:14 来自手机 | 显示全部楼层
值得全球普及
您需要登录后才可以回帖 登录 | 注册已关闭

本版积分规则

QQ|手机版|Archiver|从F到0 ( 蒙ICP备17002595号-1 )
蒙公网安备15010402000325号

腾讯云安全认证

GMT+8, 2024-4-26 08:12 , Processed in 0.996057 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表