102

I was wondering, is there a way to create a timestamp in c# from a datetime? I need a millisecond precision value that also works in Compact Framework(saying that since DateTime.ToBinary() does not exist in CF).

My problem is that i want to store this value in a database agnostic way so i can sortby it later and find out which value is greater from another etc.

Piotr Kula
  • 9,597
  • 8
  • 59
  • 85
Kostas Konstantinidis
  • 13,347
  • 10
  • 48
  • 61
  • 2
    The accepted answer here gives a nice solution, but if you want a real timestamp, check out this Q/A: http://stackoverflow.com/questions/9814060/how-to-convert-datetime-to-timestamp-using-c-netignoring-current-timezone/9814280#9814280 – inanutshellus Nov 03 '12 at 15:01

6 Answers6

207

I always use something like the following:

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

This will give you a string like 200905211035131468, as the string goes from highest order bits of the timestamp to lowest order simple string sorting in your SQL queries can be used to order by date if you're sticking values in a database

RobV
  • 28,022
  • 11
  • 77
  • 119
  • 5
    How come you get 21 months and only get 12? :) – PaulB May 21 '09 at 12:48
  • 2
    The token for year should be lowercase here: return value.ToString("yyyyMMddHHmmssffff"); – Don Cote Nov 02 '09 at 21:18
  • 1
    @RobV The question asks for millisecond precision, so you need 3 'f's at the end. Your 4 'f's give 100 microsend precision. – Evgeniy Berezovsky Dec 04 '14 at 23:50
  • 2
    Be aware, that Compact Framework does not transfer the milliseconds. They will always be 0. You have to mod the code and add something like this: int tick = Environment.TickCount % 1000; int ms = (tick >= MOffset) ? (tick - MOffset) : (1000 - (MOffset - tick)); ms = Math.Min(999, Math.Max(0, ms)); – Redwolf Apr 24 '17 at 15:38
44

I believe you can create a unix style datestamp accurate to a second using the following

//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();

Adjusting the denominator allows you to choose your level of precision

Voxel
  • 540
  • 4
  • 5
20

You could use the DateTime.Ticks property, which is a long and universal storable, always increasing and usable on the compact framework as well. Just make sure your code isn't used after December 31st 9999 ;)

Frans Bouma
  • 8,259
  • 1
  • 27
  • 28
  • When you say "always increasing" - there's no guarantee that two calls to DateTime.UtcNow.Ticks will give different values though, is there? In other words you still need some caution before you use it as a unique timestamp. – Jon Skeet May 21 '09 at 09:38
  • actually i just used it and i have duplicate values at some points. – Kostas Konstantinidis May 21 '09 at 09:46
  • @Jon: with always increasing I meant: it's not a tickcount which flips every 48 days or so, it's a real tick count which increases over time, so a higher value is always a later timestamp. – Frans Bouma May 21 '09 at 11:03
  • 9
    @Konstantinos: you can't avoid duplicates if you use timestamps. Timestamps aren't used for unique keys, but for marking a time. You said you needed millisecond precision, and ticks has 100ns precision. The thing is that you will have duplicates. If you don't want that you need a unique sequence in the DB, which is unfortunately not db agnostic. – Frans Bouma May 21 '09 at 11:05
  • 3
    "it's a real tick count which increases over time". But the system clock can go backwards - e.g. at the end of daylight saving time if you are using local time, or because the system clock was adjusted. – Joe May 21 '09 at 14:33
  • @Joe: true. Though isn't any other timestamp which isn't based on a central sequence but on the actual time suffering from that same drawback? – Frans Bouma May 22 '09 at 09:46
  • 1
    @Frans: absolutely. I only made the comment because people should think about the implications of the solution they choose. For example I'd use UTC rather than local time to at least eliminate the problems of DST. – Joe May 22 '09 at 20:49
  • @Frans Bouma The thing is that it gave me duplicated for a sequential operation that had at least 0.3 second + difference between it. I don't know if this is a compact framework peculiarity but it's strange since you say that it has a 100ns precision to give me duplicate values for sequential operations that are not that fast between the timestamp recordings... – Kostas Konstantinidis May 24 '09 at 10:57
  • 1
    @konstantinos: hmm... the docs say it has 100ns precision, so it's odd indeed that it has not that precision as documented. Perhaps it's the compact framework indeed, it's not a framework without bugs – Frans Bouma May 24 '09 at 15:26
  • @Frans: I know this is old but... 100ns precision is not the same as 100ns **accuracy**. It may give you values with enough digits to see the 100ns space but the Windows system clock is usually only accurate to somewhere between 1 and 15 __milliseconds__. In other words, nanosecond-precision is a little useless. However, Konstantinos' time with 0.3 second interval is a little weird (because it is far more than 15ms). – Moshe Katz May 30 '12 at 22:09
  • Not weird at all since `DateTime.Now` in the Compact Framework is tied to the OS real time clock, which on most hardware only has a 1-second resolution. Device OEMs can make it high resolution, but very few choose to. – ctacke Dec 05 '14 at 17:21
5

You can also use

Stopwatch.GetTimestamp().ToString();
Pang
  • 9,564
  • 146
  • 81
  • 122
mgokhanbakal
  • 1,679
  • 1
  • 20
  • 26
4

when you need in a timestamp in seconds, you can use the following:

var timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalSeconds;
Michele La Ferla
  • 6,775
  • 11
  • 53
  • 79
Adi_Pithwa
  • 421
  • 5
  • 7
2

If you want timestamps that correspond to actual real times BUT also want them to be unique (for a given application instance), you can use the following code:

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;
       }
   }
}
Ian Mercer
  • 38,490
  • 8
  • 97
  • 133