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时间?

提前谢谢。

Unix时间-纳秒

计算本身并不困难:

long UnixTime()
{
    DateTime epochStart=new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    return (DateTime.UtcNow - epochStart).Ticks*100;
}

DateTimeTimeSpan内部存储积分量的刻度,其中一个刻度为100ns。我还将epoch开始指定为UTC时间,因为我认为用不同的Kind减去DateTime s是很难看的,即使它有效。

但CCD_ 5的准确度很低。它仅每隔几毫秒更新一次(典型值在1ms和16ms之间变化(。


为了获得恒定的帧速率,您可以使用StopWatch,因为您不需要绝对时间。但是,如果你走那条路,你一定要忙着等待。由于Thread.Sleep、定时器,。。。受到同样的限制。

或者,您可以使用timeBeginPeriod(1) API强制窗口每1ms更新一次时钟和运行一次计时器。但这是一个全球性的环境,会增加电力消耗。不过,这总比忙着等要好。

为了测量时间差异,可以使用基于QueryPerformanceCounterStopWatch,但这也会带来一系列问题,例如不同内核之间的去同步。我见过当你的线程被安排在另一个核心上时,机器的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
    }