2019-10-11 11:31:01 weixin_38664232 阅读数 9

unix时间戳通常有10位和13位的区别:

  • 10位是包含年月日时分秒,13位包含了毫秒

获取时间戳:

#采用time模块
time_stamp=time.time()

或者

#datetime模块
time_stamp=datetime.datetime(2019,10,10,0,0,0).timestamp()

将时间戳转换为年-月-日 时:分:秒格式:

local_time=time.localtime(time_stamp)
dt=time.strftime('%Y-%m-%d %H:%M:%S',local_time)

 

2008-05-09 22:26:00 gooseli 阅读数 3200
实时时钟在嵌入式系统中应用非常广泛,一些芯片还内置了实时时钟。实际应用中往往使用外接I2C总线带电池时钟,系统上电后读取I2C总线时钟,初始化内部实时时钟,程序获取时间直接读内部实时时钟就可以了。
PHLIPS公司的ARM都内置了年月日时分秒格式的实时时钟,很好用;但是其他公司的产品并不具备这个功能,一部分只能记秒;51等简单单片机甚至没有内部实时时钟,一般需要使用中断程序累计秒。

看来Unix时间和年月日时分秒时间格式转换还是很有必要详细分析分析。其实这部分工作电脑很早就实现了,其算法也非常成熟,只不过这些底层的东西平时我们不注意罢了。
下面先看一段Linux年月日转时分秒的算法,听说这个算法是目前最高效的算法:

typedef        struct _DATE_TIME                    //年月日时分秒毫秒
{
    unsigned 
short year;
    unsigned 
char month;
    unsigned 
char day;
    unsigned 
char hour;
    unsigned 
char minute;
    unsigned 
char second;
    unsigned 
short msel;                        //millisecond
}
 DATE_TIME;


long long rtt_mktime(DATE_TIME time)
{
    
long long res;

    
// 1..12 -> 11,12,1..10, Puts Feb last since it has leap day
    if (time.month <= 2)
    
{
        time.month 
+= 10;
        time.year 
-= 1;
    }

    
else
    
{
        time.month 
-= 2;
    }


    
/*
    // Calculate how much days from 1970 to today
    res = 59;                            //31@0001-January and 28@0001-February
    res += (time.year - 1) * 365;        //at least 365 days one year
    res += time.year / 4 - time.year / 100 + time.year / 400;    //leap years from 0001
    res += 367 * time.month / 12 - 30;    //days from March(0.5/7<=slope<0.5/5)
    res += time.day - 1;                //days
    res -= 719162;                        //days from 0001-1-1 to 1970-1-1
    // Calculate how much seconds
    res = ( (res * 24 + time.hour) * 60 + time.minute) * 60 + time.second;
    
*/

    
///*
    res = (long long)(time.year/4 - time.year/100 + time.year/400+
            
367*time.month/12 + time.day +
            time.year
*365 - 719499;
    res 
= ((res*24 + time.hour        // now have hours
            )*60 + time.minute            // now have minutes
           )*60 + time.second;            // finally seconds
    
//*/

    
return res;
}

DATE_TIME是我自己定义的时间格式数据结构。

年月日时分秒转换为Unix秒时间有两个难点:闰年的计算和月份天数的计算如何能不用判断语句直接利用数学函数来计算,一个看似简单的数字游戏。
首先要注意公元纪年没有公元前0年和公元0年,公元后的第一天是0001年1月1日。

闰年的计算可以比较简单:0001年到当年共有year/4-year/100+year/400个,闰年的天数是366天;所以从0001年到当年共有(year-1)*365 + year/4-year/100+year/400天。
从1月到当月的天数计算起来比较复杂,但是从3月当当月的天数可以用函数来表示;我们可以使用一次函数表示,斜率大于等于30.5+0.5/7,小于30.5+0.5/5,以斜率30.5+0.5/6为例:y=ax+b,a=30.5+0.5/6=367/12,b=-30,有兴趣的朋友可以算一下,结果取整数就是3月到当月的天数:0,31,61,92,122,153,184,214,245,275,306,337。
为了能够使用巧妙的函数,我们需要假设一年是从3月开始的,步骤如下:
首先调整月份,一月和二月当作上一年的最后两个月;
由于调整了月份,调整后的0001年1月即调整前的0001年3月实际上已经有0001年1月31天和0001年2月28天;
由于公元纪年没有0年,所以调整后的0001年到调整后的当年共有(year-1)*365 + year/4-year/100+year/400天;
从调整后的1月到调整后的当月共有367*month/12-30天;
日期也是从1日开始的,从1日到当日共day-1天;

最后将0001年到当天的天数计算出来,减去0001年到1970年的天数719162,即是Unix天数,这样就可以得到Unix秒了。


2 年月日时分秒转Unix时间函数

void rtt_localtime(long long res, DATE_TIME *time)
{
    
const int monthLengths[2][13= {
        
0315990120151181212243273304334365},
        
0316091121152182213244274305335366},
    }
;
    
const int yearLengths[2= 365366 };
    
int year;
    
int month;
    
int minMonth;
    
int maxMonth;
    
    
int days;
    
int clock;
    
int isLeap;
    
    days 
= res / 86400;
    clock 
= res % 86400;
    
if(clock < 0)
    
{
        clock 
+= 86400;
        days 
-= 1;
    }

    
    
////////////////////////////////////////////////////////////////////////////
    // Calcaulate year, 11323=0x3A4FC880/86400; 13879=0x47798280/86400
    ///////////////////////////////////////////////////////////////////////////    
    if(days >= 0)
    
{
        year 
= days/366;
        days 
-= year*365 + (year+1)/4 - (year+69)/100 + (year+369)/400;
        
        
for(time->year = year + 1970; ; time->year++)
        
{
            isLeap 
= rtt_isleap(time->year);
            
if(days < yearLengths[isLeap])
            
{
                
break;
            }

            days 
-= yearLengths[isLeap];
        }

    }

    
else
    
{
        year 
= days/366;
        days 
-= year*365 + (year-2)/4 - (year-30)/100 + (year-30)/400;
        
        
for(time->year = year + 1970 - 1; ; time->year--)
        
{
            isLeap 
= rtt_isleap(time->year);
            days 
+= yearLengths[isLeap];
            
            
if(days >= 0)
            
{
                
break;
            }

        }

    }
    
    
    
//////////////////////////////////////////////////////////////////////////
    // compute month and day, use the half search save time
    ///////////////////////////////////////////////////////////////////////////
    minMonth = 0;
    maxMonth 
= 12;
    
for(month = 5; month < 12 && month > 0; month = (minMonth + maxMonth) / 2)
    
{
        
// days between monthLengths[month]<=days<monthLengths[month+1]
        if(days < monthLengths[isLeap][month])    //too big
        {
            maxMonth 
= month;
        }

        
else if(days >= monthLengths[isLeap][month + 1])    //too small
        {
            minMonth 
= month;
        }

        
else    //so it is
        {
            
break;
        }

    }

    days 
-= monthLengths[isLeap][month];
    time
->month = month + 1;
    
    time
->day = days + 1;
    
    
    
//////////////////////////////////////////////////////////////////////////
    // Calcaulate hour minute and second
    //////////////////////////////////////////////////////////////////////////
    time->hour = clock / 3600;        //3600s one hour
    clock = clock % 3600;
    time
->minute = clock / 60;        //60s one minute
    time->second = clock % 60;        //ms
}

首先将天数和秒数分开,如果Unix秒为负,表示当前为1970年前。

Unix天数为正,当前年份在1970年之后,至少为days/366+1970年,首先假设当年为year=days/366+1970年;
从1970年到假设年year的闰年数为(year+1)/4-(year+69)/100+(year+369)/400,从1970年到假设年year共有(year-1970)*365 + (year+1)/4-(year+69)/100+(year+369)/400;
适当调整假设年这样我们就很快找到当前年份了。
Unix天数为负,则当前年份为1970年前,只不过从当前年到1970年的闰年数为(year-2)/4-(year-30)/100+(year-30)/400。

月份的计算采用二分法查找的方法,如果大于等于本月总天数,小于下一个月的总天数,则本月即为当前月;
最后剩余天数加1即为当日。
2014-05-15 11:38:33 X_Craft 阅读数 1491

Unix时间是一种UNIX或类UNIX系统使用的时间表示方式,定义为从协调世界时UTC 1970年01月01日00时00分00秒起至现在的总秒数。相关知识请参考博文UNIX时间及相关概念

UNIX时间的转换在本章中这里更像是一个引子,引出了.Net中关于时间、时区和时差相关知识点。

在.Net时将某一时区时间转换成UNIX时间涉及到以下几个方面:

TimeSpan
用于表示一个时间间隔,即时间差
其中TotalSeconds属性以秒为单位表示当前TimeSpan结构值,Ticks属性以Tick为单位表示当前TimeSpan结构值
Tick中译为滴答也称为刻度,TimeSpan.TicksPerSecond常量字段用于表示一秒的刻度(滴答)数
一滴答 = 1000万分之一秒 = 万分之一毫秒 = 100纳秒

            DateTime dt1 = Convert.ToDateTime("2014/05/06 10:10:00");
            DateTime dt2 = Convert.ToDateTime("2014/05/06 10:15:00");
            TimeSpan ts = dt2 - dt1;
            Debug.WriteLine("TotalSeconds:{0} \t Ticks:{1} \t TicksPerSecond:{2}", ts.TotalSeconds, ts.Ticks, TimeSpan.TicksPerSecond);
            //output:
            //  TotalSeconds:300 	 Ticks:3000000000 	 TicksPerSecond:10000000

DateTime
表示时间上的一刻,通常以日期和当天的时间表示。

时间最重要的一个属性是时区,没有时区属性的时间不是一个完整的时间,有了时区就能得到时差,而后才能+-时差最终得到标准UTC时间

DateTime中与时区相关的属性和方法有Now、UtcNow、ToLocalTime()、ToUniversalTime()和Kind等

Now属性:获取一个 DateTime 对象,该对象设置为此计算机上的当前日期和时间,表示为本地时间。
UtcNow属性:获取一个 DateTime 对象,该对象设置为此计算机上的当前日期和时间,表示为协调通用时间 (UTC)。

ToLocalTime()方法:将当前 DateTime 对象的值转换为本地时间。
ToUniversalTime()方法:用于将当前 DateTime 对象的值转换为协调世界时 (UTC)。

那么,如何知道一个时间是本地时间还是UTC时间呢,这取决于DateTime的Kind属性

Kind属性:获取一个值,该值指示由此实例表示的时间是基于本地时间、协调世界时 (UTC),还是两者皆否。

Kind属性是一个枚举类型DateTimeKind,DateTimeKind枚举有三个成员
DateTimeKind.Local  表示的时间为本地时间
DateTimeKind.Unspecified 表示的时间既未指定为本地时间,也未指定为协调通用时间 (UTC)。
DateTimeKind.Utc  表示的时间为 UTC。

直接赋值、Now、UtcNow 三种不同的时间输入方式得到三种不同的Kind及时间

            DateTime dt1 = Convert.ToDateTime("2014/05/06 10:10:00");
            DateTime dt2 = DateTime.Now;
            DateTime dt3 = DateTime.UtcNow;
            Debug.WriteLine("dt1.kind:{0} \t dt2.kind:{1} \t dt3.kind:{2}", dt1.Kind, dt2.Kind, dt3.Kind);
            Debug.WriteLine("dt1:{0} \t dt2:{1} \t dt3:{2}", dt1, dt2, dt3);
            //output:
            //  dt1.kind:Unspecified 	 dt2.kind:Local 	 dt3.kind:Utc
            //  dt1:05/06/2014 10:10:00 	 dt2:05/15/2014 11:31:48 	 dt3:05/15/2014 03:31:48


而ToUniversalTime()和ToLocalTime()的转换也依赖于Kind,这里需要注意的是
当待转DateTime的Kind为Unspecified时,ToLocalTime()假定待转DateTime为UTC时间,转换等同于Kind为UTC,ToUniversalTime()假定待转DateTime为Local时间,转换等同于Kind为Local
当待转DateTime的Kind为Local时,ToUniversalTime()方法什么也不作,直接返回原待转时间
当待转DateTime的Kind为UTC时,ToUniversalTime()方法什么也不作,直接返回原待转时间

            DateTime dt1 = Convert.ToDateTime("2014/05/06 10:10:00");
            DateTime dt2 = dt1.ToLocalTime();
            DateTime dt3 = dt1.ToUniversalTime();
            Debug.WriteLine("dt1.kind:{0} \t dt2.kind:{1} \t dt3.kind:{2}", dt1.Kind, dt2.Kind, dt3.Kind);
            Debug.WriteLine("dt1:{0} \t dt2:{1} \t dt3:{2}", dt1, dt2, dt3);
            //output:
            //  dt1.kind:Unspecified 	 dt2.kind:Local 	 dt3.kind:Utc
            //  dt1:05/06/2014 10:10:00 	 dt2:05/06/2014 18:10:00 	 dt3:05/06/2014 02:10:00

            dt1 = DateTime.Now;
            dt2 = dt1.ToLocalTime();
            Debug.WriteLine("dt1.kind:{0} \t dt2.kind:{1}", dt1.Kind, dt2.Kind);
            Debug.WriteLine("dt1:{0} \t dt2:{1}", dt1, dt2);
            //output:
            //  dt1.kind:Local 	 dt2.kind:Local
            //  dt1:05/15/2014 11:33:46 	 dt2:05/15/2014 11:33:46

            dt1 = DateTime.UtcNow;
            dt2 = dt1.ToUniversalTime();
            Debug.WriteLine("dt1.kind:{0} \t dt2.kind:{1}", dt1.Kind, dt2.Kind);
            Debug.WriteLine("dt1:{0} \t dt2:{1}", dt1, dt2);
            //output:
            //  dt1.kind:Utc 	 dt2.kind:Utc
            //  dt1:05/15/2014 03:33:46 	 dt2:05/15/2014 03:33:46


DateTime也有一个Ticks属性,与TimeSpa不同的是,它表示的是自 0001 年 1 月 1 日午夜 12:00:00(DateTime.MinValue)以来经过的以Tick为单位的间隔数。

Local和UTC之间的转换涉及到时区即时差,在.Net中DateTimeOffset、TimeZoneInfo等类型用于时区时差

DateTimeOffset
DateTimeOffset 结构包括一个 DateTime 值以及一个 Offset 属性,该属性用于确定当前 DateTimeOffset 实例的日期和时间与协调世界时 (UTC) 之间的差值。 因为 DateTimeOffset 结构确切地定义了相对于 UTC 的日期和时间,所以它不包括 Kind 成员,这一点与 DateTime 结构相同。

DateTimeOffset构造函数更好的说明了它的作用

public DateTimeOffset(
	DateTime dateTime
)

使用指定的 DateTime 值初始化 DateTimeOffset 结构的新实例。
此构造函数的行为取决于 dateTime 参数的 DateTime.Kind 属性值:
如果 DateTime.Kind 的值为 DateTimeKind.Utc,则新实例的 DateTime 属性被设置为 dateTime,Offset 属性被设置为 Zero。
如果 DateTime.Kind 的值为 DateTimeKind.Local 或 DateTimeKind.Unspecified,则新实例的 DateTime 属性被设置为 dateTime,Offset 属性被设置为本地系统当前时区的偏移量。

            DateTimeOffset dtf1 = new DateTimeOffset(Convert.ToDateTime("2014/05/06 10:10:00"));
            DateTimeOffset dtf2 = DateTimeOffset.Now;
            DateTimeOffset dtf3 = DateTimeOffset.UtcNow;
            Debug.WriteLine("dtf1:{0}  dtf1.Offset:{1}  df1.DateTime.Kind:{2}", dtf1, dtf1.Offset, dtf1.DateTime.Kind);
            Debug.WriteLine("dtf2:{0}  dtf2.Offset:{1}  df2.DateTime.Kind:{2}", dtf2, dtf2.Offset, dtf2.DateTime.Kind);
            Debug.WriteLine("dtf3:{0}  dtf3.Offset:{1}  df3.DateTime.Kind:{2}", dtf3, dtf3.Offset, dtf3.DateTime.Kind);
            //output:
            //  dtf1:05/06/2014 10:10:00 +08:00  dtf1.Offset:08:00:00  df1.DateTime.Kind:Unspecified
            //  dtf2:05/15/2014 11:43:28 +08:00  dtf2.Offset:08:00:00  df2.DateTime.Kind:Unspecified
            //  dtf3:05/15/2014 03:43:28 +00:00  dtf3.Offset:00:00:00  df3.DateTime.Kind:Unspecified


TimeZoneInfo(TimeZone的替代)
表示世界上的任何时区。 其中BaseUtcOffset属性为TimeSpan类型,用于获取对象所处时区的标准时间与协调世界时 (UTC) 之间的时差。

            DateTime dt1 = Convert.ToDateTime("2014/05/06 10:10:00");
            TimeZoneInfo tziCN = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
            DateTime dt2 = TimeZoneInfo.ConvertTime(dt1, tziCN, TimeZoneInfo.Utc);
            Debug.WriteLine("dt1:{0} \t dt2:{1} \t BaseUtcOffset:{2}", dt1, dt2, tziCN.BaseUtcOffset);
            Debug.WriteLine("id:{0} \t DaylightName:{1} \t DisplayName:{2}", tziCN.Id, tziCN.DaylightName, tziCN.DisplayName);
            //output:
            //  dt1:05/06/2014 10:10:00 	 dt2:05/06/2014 02:10:00 	 BaseUtcOffset:08:00:00
            //  id:China Standard Time 	 DaylightName:中国夏令时 	 DisplayName:(UTC+08:00)北京,重庆,香港特别行政区,乌鲁木齐

            foreach (TimeZoneInfo tzi in TimeZoneInfo.GetSystemTimeZones())
            {
                Debug.WriteLine("id:{0} \t DaylightName:{1} \t DisplayName:{2}", tzi.Id, tzi.DaylightName, tzi.DisplayName);
            }
            // etc..


综上,将某一时区时间转换为UNIX时间有多种方式,但时间、时区或时差是必不可少的参数。

 

TimeSpan 结构 (System)
http://msdn.microsoft.com/zh-cn/library/system.timespan.aspx

DateTime 结构 (System)
http://msdn.microsoft.com/zh-cn/library/system.datetime.aspx

DateTimeOffset 结构 (System)
http://msdn.microsoft.com/zh-cn/library/system.datetimeoffset.aspx

TimeZoneInfo 类 (System)
http://msdn.microsoft.com/zh-cn/library/system.timezoneinfo.aspx

纳秒
http://baike.baidu.com/view/187741.htm?fr=aladdin

 

 

 

2016-09-20 23:13:22 datou0529 阅读数 799

Java的做法

  • 时间戳转化为Date(or String)
       SimpleDateFormat format =  new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
       Long time=new Long(445555555);
       String d = format.format(time);
       Date date=format.parse(d);
       System.out.println("Format To String(Date):"+d);
       System.out.println("Format To Date:"+date);
  • Date(or String)转化为时间戳
       SimpleDateFormat format =  new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
       String time="1970-01-06 11:45:55";
       Date date = format.parse(time);
       System.out.print("Format To times:"+date.getTime());

JavaScript的做法

以下内容来自 http://shiningray.cn/toys/unix-timestamp#

  • 时间戳转普通时间格式
function EpochToHuman(val){
    var datum = new Date(val * 1000);
    console.log(datum.toGMTString(),'*',datum.toLocaleString());//两种形式输出
}
Input:1474381596
Output: Tue, 20 Sep 2016 14:26:36 GMT * 2016/9/20 下午10:26:36
  • 普通时间格式转时间戳
function HumanToEpoch(y,m,d,h,mn,ss){
        var datum = new Date(Date.UTC(y,m-1,d,h,mn,ss));
        console.log(datum.getTime()/1000.0);
}
Input:2016,9,20,14,26,36
Ouput:1474381596
// 对Date的扩展,将 Date 转化为指定格式的String
// 月(M)、日(d)、小时(H)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符, 
// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) 
// 例子: 
// (new Date()).Format("yyyy-MM-dd HH:mm:ss.S") ==> 2006-07-02 08:09:04.423 
// (new Date()).Format("yyyy-M-d H:m:s.S")      ==> 2006-7-2 8:9:4.18 
Date.prototype.Format = function (fmt) { //author: meizz 
    var o = {
        "M+": this.getMonth() + 1, //月份 
        "d+": this.getDate(), //日 
        "H+": this.getHours(), //小时 
        "m+": this.getMinutes(), //分 
        "s+": this.getSeconds(), //秒 
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度 
        "S": this.getMilliseconds() //毫秒 
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}
调用: 
var time1 = new Date().Format("yyyy-MM-dd");
var time2 = new Date().Format("yyyy-MM-dd HH:mm:ss"); 
2011-02-23 11:15:44 iteye_7106 阅读数 13

竟然忘记了,记下来,看你还能忘

 

(完整的 年月日时分秒)

 

  php中UNIX时间戳转换为日期用函数 : date()

  date('Y-m-d H:i:s', 1156219870);

  php中日期转换为UNIX时间戳用函数 :strtotime()

  strtotime('2010-03-24 08:15:42');

 

 

 

mysql的

 

  UNIX时间戳转换为日期用函数 : FROM_UNIXTIME()

  select FROM_UNIXTIME(1156219870);

  日期转换为UNIX时间戳用函数 : UNIX_TIMESTAMP()

  Select UNIX_TIMESTAMP(’2006-11-04 12:23:00′);

没有更多推荐了,返回首页