ibcadmin 发表于 2017-1-18 09:32:23

C#生成唯一时间戳ID代码分享


/// <summary>
    /// 时间戳ID
    /// </summary>
    public class TimestampID
    {
      private long _lastTimestamp;
      private long _sequence; //计数从零开始
      private readonly DateTime? _initialDateTime;
      private static TimestampID _timestampID;
      private const int MAX_END_NUMBER = 9999;

      private TimestampID(DateTime? initialDateTime)
      {
            _initialDateTime = initialDateTime;
      }

      /// <summary>
      /// 获取单个实例对象
      /// </summary>
      /// <param name="initialDateTime">最初时间,与当前时间做个相差取时间戳</param>
      /// <returns></returns>
      public static TimestampID GetInstance(DateTime? initialDateTime = null)
      {
            if (_timestampID == null) Interlocked.CompareExchange(ref _timestampID, new TimestampID(initialDateTime), null);
            return _timestampID;
      }

      /// <summary>
      /// 最初时间,作用时间戳的相差
      /// </summary>
      protected DateTime InitialDateTime
      {
            get
            {
                if (_initialDateTime == null || _initialDateTime.Value == DateTime.MinValue) return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                return _initialDateTime.Value;
            }
      }
      /// <summary>
      /// 获取时间戳ID
      /// </summary>
      /// <returns></returns>
      public string GetID()
      {
            long temp;
            var timestamp = GetUniqueTimeStamp(_lastTimestamp, out temp);
            return $"{timestamp}{Fill(temp)}";
      }

      private string Fill(long temp)
      {
            var num = temp.ToString();
            IList<char> chars = new List<char>();
            for (int i = 0; i < MAX_END_NUMBER.ToString().Length - num.Length; i++)
            {
                chars.Add('0');
            }
            return new string(chars.ToArray()) + num;
      }

      /// <summary>
      /// 获取一个时间戳字符串
      /// </summary>
      /// <returns></returns>
      public long GetUniqueTimeStamp(long lastTimeStamp, out long temp)
      {
            lock (this)
            {
                temp = 1;
                var timeStamp = GetTimestamp();
                if (timeStamp == _lastTimestamp)
                {
                  _sequence = _sequence + 1;
                  temp = _sequence;
                  if (temp >= MAX_END_NUMBER)
                  {
                        timeStamp = GetTimestamp();
                        _lastTimestamp = timeStamp;
                        temp = _sequence = 1;
                  }
                }
                else
                {
                  _sequence = 1;
                  _lastTimestamp = timeStamp;
                }
                return timeStamp;
            }
      }

      /// <summary>
      ///
      /// </summary>
      /// <returns></returns>
      private long GetTimestamp()
      {
            if (InitialDateTime >= DateTime.Now) throw new Exception("最初时间比当前时间还大,不合理");
            var ts = DateTime.UtcNow - InitialDateTime;
            return (long)ts.TotalMilliseconds;
      }
    }

剑弑 发表于 2017-1-18 09:50:00

楠哥,要是他们没有C# 6.0的话运行不了的还是写5.0的好

ibcadmin 发表于 2017-1-18 10:01:05

剑弑 发表于 2017-1-18 09:50
楠哥,要是他们没有C# 6.0的话运行不了的还是写5.0的好

是的   时间久了 就会用了 vs不升级都用不了

Amy尾巴 发表于 2017-1-18 10:02:22

:D

cmccant 发表于 2017-1-26 08:46:34

谢谢分享。
页: [1]
查看完整版本: C#生成唯一时间戳ID代码分享