在C#中创建时间戳的函数


101

我想知道,有没有办法从日期时间在C#中创建时间戳?我需要一个毫秒精度值,该精度值也可以在Compact Framework中使用(假设因为CF中不存在DateTime.ToBinary())。

我的问题是我想以数据库不可知的方式存储此值,以便以后可以对它进行排序并找出另一个值中更大的一个,等等。


2
这里接受的答案给出了一个很好的解决方案,但如果你想真正的时间戳,看看这个Q / A: stackoverflow.com/questions/9814060/...
inanutshellus

Answers:


206

我总是使用类似以下的内容:

public static String GetTimestamp(this DateTime value)
{
    return value.ToString("yyyyMMddHHmmssfff");
}

这将为您提供一个类似于200905211035131468的字符串,因为该字符串从时间戳的最高位到最低位,如果您要将值粘贴在数据库中,则可以使用SQL查询中的简单字符串排序按日期进行排序


5
你怎么会得到21个月而只有12个月呢?:)
PaulB

2
年的令牌在此处应为小写:return value.ToString(“ yyyyMMddHHmmssffff”);
Don Cote

1
@RobV这个问题要求毫秒精度,因此最后需要3'f'。您的4'f可提供100微发送的精度。
尤金·别列索夫斯基

2
请注意,Compact Framework不会传输毫秒。它们将始终为0。您必须修改代码并添加如下内容:int tick = Environment.TickCount%1000; int ms =(tick> = MOffset)吗?(tick-MOffset):(1000-(MOffset-tick)); ms = Math.Min(999,Math.Max(0,ms));
Redwolf

43

我相信您可以使用以下命令创建准确到一秒钟的unix样式日期戳

//Find unix timestamp (seconds since 01/01/1970)
long ticks = DateTime.UtcNow.Ticks - DateTime.Parse("01/01/1970 00:00:00").Ticks;
ticks /= 10000000; //Convert windows ticks to seconds
timestamp = ticks.ToString();

调整分母可让您选择精度等级


19

您可以使用DateTime.Ticks属性,该属性是一个长期且通用的可存储属性,始终在紧凑型框架上也可以使用。只要确保您的代码在9999年12月31日之后就不再使用;)


当您说“总是增加”时-无法保证两次调用DateTime.UtcNow.Ticks会给出不同的值,是吗?换句话说,在将其用作唯一时间戳之前,仍需要谨慎。
乔恩·斯基特

9
@Konstantinos:如果使用时间戳,则无法避免重复。时间戳并非用于唯一键,而是用于标记时间。您说您需要毫秒级的精度,滴答的精度为100ns。问题是您将有重复项。如果您不希望在数据库中需要一个唯一的序列,那么不幸的是这与数据库无关。
弗朗斯·布玛

3
“这是一个真实的滴答数,随着时间的推移而增加”。但是系统时钟可能会倒退-例如,如果您使用的是当地时间,则在夏令时结束时,或者因为系统时钟已调整。

1
@弗兰斯:绝对。我之所以发表评论,是因为人们应该考虑他们选择的解决方案的含义。例如,我将使用UTC而非本地时间来至少消除DST问题。

1
@konstantinos:嗯...文档说它具有100ns的精度,所以奇怪的是它没有所记录的精度。也许确实是紧凑的框架,不是没有错误的框架
Frans Bouma


4

当您需要几秒钟的时间戳时,可以使用以下方法:

var timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalSeconds;

2

如果希望与实际实时时间相对应的时间戳,但又希望它们是唯一的(对于给定的应用程序实例),则可以使用以下代码:

public class HiResDateTime
{
   private static long lastTimeStamp = DateTime.UtcNow.Ticks;
   public static long UtcNowTicks
   {
       get
       {
           long orig, newval;
           do
           {
               orig = lastTimeStamp;
               long now = DateTime.UtcNow.Ticks;
               newval = Math.Max(now, orig + 1);
           } while (Interlocked.CompareExchange
                        (ref lastTimeStamp, newval, orig) != orig);

           return newval;
       }
   }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.