1

I want to store a timestamps in memory (billions of values). The main operations are read-to-memory and read-from-memory, no need in DateTime-specific methods. For compatibility with other services, I want to use unix timestamp format in seconds (to avoid conversions).

So, I want to use special data type instead of just long in my code.

I found that I can not "make alias name" for simple data type like long, which I can fully use outside assembly.

So, I want to implement Timestamp as struct with single long field and some methods (ex, ToDateTime, some operator overloading, etc.), because structs are "non-reference data type" and they keep my memory.

Is making a struct is bad idea?

Any alternatives to make code strongly-typed, to redefine Method (long, long) to Method (Timestamp, StepCount)

Stefan
  • 17,448
  • 11
  • 60
  • 79
filimonic
  • 3,988
  • 2
  • 19
  • 26
  • *"I want to store a timestamps in memory (billions of values)"*; how much mem do you have? (just wondering) – Stefan May 05 '20 at 19:48
  • Struct is fine, I'm sure. – Wyck May 05 '20 at 19:52
  • 5
    Let's forget about the number of values for a moment. Wrapping a 64-bit integer in a struct to provide timestamp-specific operations will be fine. *That's exactly what `DateTime` is.* – madreflection May 05 '20 at 19:53
  • @madreflection, thanks. Just looked to DateTime sources. There is support for DateTimeKind (only 62 bits are used for timestamp and 2 bits for kind), which may be a headache in my case. I will use custom struct. – filimonic May 05 '20 at 20:58
  • `DateTime` and Unix timestamps are framed differently (Christopher's answer explains how `DateTime` is framed in ticks) so go for it if that's what's right for you. Before you do, though, take a look at the answers to [this question](https://stackoverflow.com/questions/249760/how-can-i-convert-a-unix-timestamp-to-datetime-and-vice-versa) in case that handles it well enough for your needs. – madreflection May 05 '20 at 21:08

2 Answers2

5

DateTime interally uses Ticks as the value. Almost every other function call and property is just a reinterpretation of the Ticks value.

Ticks are way more granular then seconds, by 7 orders of magnitude.

"A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond, or 10 million ticks in a second.

The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 in the Gregorian calendar, which represents MinValue."

However the internal clock is not actually that precise. DateTime.Now might only update every ~30 ms or less. For precise measurements, you would have to use the StopWatch class instead.

Of course with Billions of values, it really becomes a question if you got the memory. The .NET Object Size, memory and array size limtis might get in the way. It might be better to store those values in a database and only look at parts of the list. Use heavy filtering in the query.

Christopher
  • 9,634
  • 2
  • 17
  • 31
0

To give you a radical alternative: there are actually some build in routines to do a proper conversion, I think containing some of the routines you're after.

From msdn:

using System;

public class Example
{
   public static void Main()
   {
      DateTimeOffset dto = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
      Console.WriteLine("{0} --> Unix Seconds: {1}", dto, dto.ToUnixTimeSeconds());

      dto = new DateTimeOffset(1969, 12, 31, 23, 59, 0, TimeSpan.Zero);
      Console.WriteLine("{0} --> Unix Seconds: {1}", dto, dto.ToUnixTimeSeconds());

      dto = new DateTimeOffset(1970, 1, 1, 0, 1, 0, TimeSpan.Zero);
      Console.WriteLine("{0} --> Unix Seconds: {1}", dto, dto.ToUnixTimeSeconds());
   }
}
// The example displays the following output:
//    1/1/1970 12:00:00 AM +00:00 --> Unix Seconds: 0
//    12/31/1969 11:59:00 PM +00:00 --> Unix Seconds: -60
//    1/1/1970 12:01:00 AM +00:00 --> Unix Seconds: 60

Or the counterpart:

public static DateTimeOffset FromUnixTimeSeconds (long seconds);

https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tounixtimeseconds?view=netcore-3.1


For this reason: yes, I think rebuilding a similar struct is a bad idea, because it's already been done. But I might be missing some context.

Stefan
  • 17,448
  • 11
  • 60
  • 79