Unix时间-纳秒
本文关键字:纳秒 时间 Unix | 更新日期: 2023-09-27 18:15:33
我目前正在使用此方法(C#(获取Unix时间(以毫秒为单位(:
long UnixTime()
{
return (long) (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalMilliseconds;
}
问题-有没有办法获得以纳秒为单位的unix时间?
提前谢谢。
计算本身并不困难:
long UnixTime()
{
DateTime epochStart=new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return (DateTime.UtcNow - epochStart).Ticks*100;
}
DateTime
和TimeSpan
内部存储积分量的刻度,其中一个刻度为100ns。我还将epoch开始指定为UTC时间,因为我认为用不同的Kind
减去DateTime
s是很难看的,即使它有效。
但CCD_ 5的准确度很低。它仅每隔几毫秒更新一次(典型值在1ms和16ms之间变化(。
为了获得恒定的帧速率,您可以使用StopWatch
,因为您不需要绝对时间。但是,如果你走那条路,你一定要忙着等待。由于Thread.Sleep
、定时器,。。。受到同样的限制。
或者,您可以使用timeBeginPeriod(1)
API强制窗口每1ms更新一次时钟和运行一次计时器。但这是一个全球性的环境,会增加电力消耗。不过,这总比忙着等要好。
为了测量时间差异,可以使用基于QueryPerformanceCounter
的StopWatch
,但这也会带来一系列问题,例如不同内核之间的去同步。我见过当你的线程被安排在另一个核心上时,机器的QueryPerformanceCounter
跳了几百毫秒。
TotalMilliseconds属性返回一个double
,该属性包含整和分数毫秒。
因此,您只需将其值乘以1000000
即可获得纳秒:
return (long) ((DateTime.UtcNow
- new DateTime(1970, 1, 1, 0, 0, 0)).TotalMilliseconds * 1000000.0);
我认为这并不容易(在普通的x86台式计算机上(,会导致精度问题。因此,首先DateTime类在这种情况下是无用的。您可以使用StopWatch
这里有一篇非常好的文章:http://www.codeproject.com/KB/testing/stopwatch-measure-precise.aspx
+1:https://stackoverflow.com/q/1416188/241506enter此处的链接描述
这个类会有所帮助。它允许您将Unix时间来回转换为Windows时间。评论可能不需要更新,但一切都很好。
public sealed class LinuxToWindowsFileTimeConverter : IValueConverter
{
static long ticksFrom1601To1970 = (long)(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) - DateTime.FromFileTimeUtc(0)).Ticks;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return new DateTime();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return new DateTime();
}
public static DateTime Convert(Int64 nanoSecsSince1970)
{
return Convert(nanoSecsSince1970, ScaleFactor.Billion);
}
/// <summary>
/// Converts from Linux seconds to Windows DateTime
/// </summary>
/// <param name="secs"></param><remarks> secs</remarks>
/// <param name="sf"></param><remarks>specifies scale factor.
/// Specify ScaleFactor.One for secs since 1970.
/// ScaleFactor.Thousand for milli (10^3) seconds since 1970.
/// ScaleFactor.Million for micro (10^6)seconds since 1970.
/// ScaleFactor.Billion for nano (10^9)seconds since 1970.
/// etc.</remarks>
/// <returns></returns>
public static DateTime Convert(Int64 secs, ScaleFactor sf)
{
long hndrdnsfrom1601 = 0;
switch(sf)
{
case ScaleFactor.Billion:
hndrdnsfrom1601 = ticksFrom1601To1970 + secs / 100;
break;
default:
// TODO: Correct for other cases.
hndrdnsfrom1601 = (long)ticksFrom1601To1970 + (secs * (long)ScaleFactor.TenMillion / (long)sf);
break;
}
return DateTime.FromFileTimeUtc(hndrdnsfrom1601);
}
public static long ConvertBack(DateTime dateTimeInUTC)
{
if (dateTimeInUTC == new DateTime())
dateTimeInUTC = new DateTime(1980, 1,1).ToUniversalTime();
long secsSince1970 = (dateTimeInUTC.ToFileTimeUtc() - ticksFrom1601To1970) * ((long)ScaleFactor.Billion / (long)ScaleFactor.TenMillion);
return secsSince1970;
}
public Int64 ConvertBack(DateTime dateTimeInUTC, CultureInfo culture)
{
return ConvertBack(dateTimeInUTC, culture, ScaleFactor.Billion);
}
/// <summary>
/// Converts from Windows file time to Linux seconds.
/// </summary>
/// <param name="dateTimeInUTC"></param>
/// <param name="culture"></param>
/// <param name="sf"></param><remarks>
/// Specify ScaleFactor.One for secs since 1970.
/// ScaleFactor.Thousand for milli (10^3) seconds since 1970.
/// ScaleFactor.Million for micro (10^6)seconds since 1970.
/// ScaleFactor.Billion for nano (10^9)seconds since 1970.
/// </remarks>
/// <returns></returns>
public Int64 ConvertBack(DateTime dateTimeInUTC, CultureInfo culture, ScaleFactor sf)
{
long secsSince1970 = (dateTimeInUTC.ToFileTimeUtc() - ticksFrom1601To1970) * ((long)sf / (long)ScaleFactor.TenMillion);
return secsSince1970;
}
}
public enum ScaleFactor : long
{
One = 1,
Ten = 10,
Hundred = 100,
Thousand = 1000,
TenThou = 10000,
HundredThou = 100000,
Million = 1000000,
TenMillion = 10000000,
HundredMillion = 100000000,
Billion = 1000000000,
TenBillion = 10000000000,
HundredBillion = 100000000000
}