DataTime.Now.Ticks精确的时间单位[转]
DataTime.Now.Ticks
getTime
public long getTime()
返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
返回: 自 1970 年 1 月 1 日 00:00:00 GMT 以来此日期表示的毫秒数。
.net DateTime.Ticks
public long Ticks {get;}
属性值
表示此实例的日期和时间的刻度数。该值介于 MinValue 和 MaxValue 之间。
备注
此属性的值为自 0001 年 1 月 1 日午夜 12:00 以来所经过时间以 100 毫微秒为间隔表示时的数字。
好了一个返回的是毫秒一个返回的是微秒,所以知道毫秒与微妙之间的转化也是有必要的
1秒=1000毫秒(ms) 1毫秒=1/1,000秒(s)
1秒=1,000,000 微秒(μs) 1微秒=1/1,000,000秒(s)
1秒=1,000,000,000 纳秒(ns)
1纳秒=1/1,000,000,000秒(s)
1秒=1,000,000,000,000 皮秒(ps)
1 毫秒 = 10^-3 秒, ------->10的-3次方 小数点从1开始向左移3位即0.001
1 微秒 = 10^-6 秒,
1 毫微秒 = 10^-9 秒,
100 毫微秒 = 10^-7 秒。
Console.WriteLine(DateTime.Now.Ticks); // 输出:633603924670937500
也就是说,从0001 年 1 月 1 日午夜 12:00:00 以来到现在已经过了 633603924670937500 * 10^-7 秒。
很少用,除非需要很精确地知道从那时(1年1月1日)开始过了多少时间。
比如精确地计算两个时间差时(想知道某段程序运行了多少毫微秒)就可以用到。
- using System;
- using System.Collections.Generic;
- class Sentence
- {
- static void Main()
- {
- long ticks0 = DateTime.Now.Ticks;
- for (int i = 0; i < int.MaxValue; i++)
- {
- // ...
- }
- long ticks1 = DateTime.Now.Ticks;
- long n = (ticks1 - ticks0) * 100;
- Console.WriteLine("上面这段程序运行了{0}毫微秒", n);
- }
- }
转换成秒比用毫微秒更直观些:
- using System;
- using System.Collections.Generic;
- class Sentence
- {
- static void Main()
- {
- long ticks0 = DateTime.Now.Ticks;
- for (int i = 0; i < int.MaxValue; i++)
- {
- // ...
- }
- long ticks1 = DateTime.Now.Ticks;
- double n = (ticks1 - ticks0) / 10000000.0;
- Console.WriteLine("上面这段程序运行了{0}秒", n);
- }
- }
获取高精度的时间差,可以用来分析页面运行时间的长短
DateTime.Now的精度是很低,这个低的意思是,两次获取的DateTime.Now的Ticks的差,只是一个较大数的整数倍。例如在我 的机器上,这个差最小是10.114ms。所以,如果我用DateTime.Now来计算时间差,那么就无法精确到10ms以内。
后来发现ASP.NET的TRACE的精度很高,用Reflector看它的实现,发现了它是使用这两个方法的:
参考MSDN:How To: Time Managed Code Using QueryPerformanceCounter and QueryPerformanceFrequency
我自己了按照这个写了个类,代码如下:
- using System;
- using System.Runtime.InteropServices;
- public class A
- {
- [DllImport("kernel32.dll")]
- static extern bool QueryPerformanceCounter([In, Out] ref long lpPerformanceCount);
- [DllImport("kernel32.dll")]
- static extern bool QueryPerformanceFrequency([In, Out] ref long lpFrequency);
- static long _f = 0;
- static public long GetTickCount()
- {
- long f = _f;
- if (f == 0)
- {
- if (QueryPerformanceFrequency(ref f))
- {
- _f = f;
- }
- else
- {
- _f = -1;
- }
- }
- if (f == -1)
- {
- return Environment.TickCount * 10000;
- }
- long c = 0;
- QueryPerformanceCounter(ref c);
- return (long)(((double)c) * 1000 * 10000 / ((double)f));
- }
- //GetTickCount()为0时的DateTime.Ticks值
- static long _tc = 0;
- //这个返回的不是真正的精确时间,但时间与时间的差是精确的。
- //GetExactNow与DateTime.Now的偏差比DateTime.Now的精度还要小,所以该偏差
- static public DateTime GetExactNow()
- {
- if (_tc == 0)
- {
- long tc = GetTickCount();
- DateTime dt = DateTime.Now;
- _tc = dt.Ticks - tc;
- return dt;
- }
- return new DateTime(_tc + GetTickCount());
- }
- }
在ASP。NET的应用,可以在Global.asax的Application_BeginRequest事件中加入代码来纪录程序开始时的TickCount:
Context.Items["BeginRequestTickCount"]=A.GetTickCount();
然后在页面输出的后面:
<html>....
<div align="center">
<%=new TimeSpan(A.GetTickCount()-(long)Context.Items["BeginRequestTickCount"]).TotalMilliseconds%>
</div>
</body></html>
这样就可以达到获取页面运行时间值了。(当然输出TotalMilliseconds后Asp.Net还要一些后期工作的,不过这个时间应该只需要0.n ms)
1秒=1000000000毫微秒 10亿
1毫秒=1000微秒
1微秒=1000毫微秒
所以1秒=1000*1000*1000=1000000000毫微秒
1毫秒=1000微秒
1微秒=1000毫微秒
1毫微秒=1纳秒
1纳秒=10埃秒
= 1000000 微秒
= 1000000000 毫微秒
= 1000000000 纳秒
= 1000000000000 皮秒
1s = 1000 ms
= 1000000 us
= 1000000000 ns
= 1000000000000 ps