So erhalten Sie den Unix-Zeitstempel in C #

Antworten:

597

Sie erhalten einen Unix-Zeitstempel in C #, indem Sie DateTime.UtcNowdie Epochenzeit vom 01.01.1970 verwenden und subtrahieren.

z.B

Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

DateTime.UtcNowkann durch jedes DateTimeObjekt ersetzt werden, für das Sie den Unix-Zeitstempel erhalten möchten.

Es gibt auch ein Feld, DateTime.UnixEpochdas von MSFT sehr schlecht dokumentiert ist, aber möglicherweise ersetzt wirdnew DateTime(1970, 1, 1)

bizzehdee
quelle
28
Kommentar im Namen von @wdhough. "Diese Antwort ist auf das Limit von Int32 beschränkt, das meiner Meinung nach 2.147.483.647 beträgt. Laut onlineconversion.com/unix_time.htm entspricht dies einer Zeit von Di, 19. Januar 2038, 03:14:07 GMT. Ich denke, jeder alternative Nummerntyp , double, long, etc wird letztendlich auch ein Limit haben, aber ich fand es erwähnenswert. Ich wähle lange hier, da ich eine ganze Zahl wollte. Ich hoffe, das hilft "
IsmailS
11
Der Unix-Zeitstempel ist traditionell eine 32-Bit-Ganzzahl und hat einen Bereich von '1970-01-01 00:00:01' UTC bis '2038-01-19 03:14:07' UTC.
the_nuts
89
Verrückt, dass die UNIX-Zeitkonvertierung nicht in der Standardbibliothek als Teil von DateTime enthalten ist.
Xingyu
7
Oder mit ganzzahliger Arythmetik:DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
Anton Petrov
2
Die subtrahierte datetime muss nicht UTC sein?
jjxtra
572

Ab .NET 4.6 gibt es DateTimeOffset.ToUnixTimeSeconds().


Dies ist eine Instanzmethode, daher wird erwartet, dass Sie sie für eine Instanz von aufrufen DateTimeOffset. Sie können auch eine beliebige Instanz von übertragen DateTime, achten Sie jedoch auf die Zeitzone .

So erhalten Sie den aktuellen Zeitstempel:

DateTimeOffset.UtcNow.ToUnixTimeSeconds()

So erhalten Sie den Zeitstempel von DateTime:

DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Bob
quelle
126
Gut. Es ist an der Zeit
bizzehdee
35
@MattBorja Zum Glück gibt es ein Int64- zu dem Zeitpunkt, an dem es vorbei ist, würden wir keine Erdjahre mehr verwenden, da es keine Erde gibt.
Bob
24
Für alle anderen, die sich fragen, können Sie den aktuellen Zeitstempel mitDateTimeOffset.Now.ToUnixTimeSeconds()
kR105
8
@bizzehdee, Wortspiel beabsichtigt?
st0le
5
Sie können den UTC-Unixtimestamp erhalten mit: DateTimeOffset.UtcNow.ToUnixTimeSeconds ()
Yair Levi
39

Sie können auch Ticks verwenden. Ich codiere für Windows Mobile, habe also nicht alle Methoden. TotalSeconds steht mir nicht zur Verfügung.

long epochTicks = new DateTime(1970, 1, 1).Ticks;
long unixTime = ((DateTime.UtcNow.Ticks - epochTicks) / TimeSpan.TicksPerSecond);

oder

TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
TimeSpan unixTicks = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
double unixTime = unixTicks.TotalSeconds;
Dave Hindle
quelle
1
Fehler bei der zweiten Lösung: Der Quelltyp 'double' kann nicht in den Zieltyp 'long' konvertiert werden.
Pixar
@Pixar: Die zweite Probe ist behoben
JBert
5
new DateTime(1970, 1, 1)Erstellt eine Zeit mit nicht angegebener KindEigenschaft. Was Sie wirklich wollen, new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)um wirklich richtig zu sein
verstimmt am
Ab .NET Core 2.1 Sie können DateTime.UnixEpoch anstelle von new DateTime (1970, 1, 1) verwenden (siehe docs.microsoft.com/en-us/dotnet/api/…
Jaa H,
27

Das benutze ich:

public long UnixTimeNow()
{
    var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
    return (long)timeSpan.TotalSeconds;
}

Beachten Sie, dass diese Methode die Zeit als Coordinated Univeral Time (UTC) zurückgibt.

Bartłomiej Mucha
quelle
(TotalSeconds hat doubleTyp; ein zu langes Casting führt zu Präzisionsverlust.)
Frankish
Sie haben Recht, aber darüber müssen wir uns mehrere tausend Jahre lang keine Sorgen machen :)
Bartłomiej Mucha
21

Das Abschneiden .TotalSecondsist wichtig, da es definiert ist alsthe value of the current System.TimeSpan structure expressed in whole fractional seconds.

Und wie wäre es mit einer Erweiterung für DateTime? Der zweite ist wahrscheinlich verwirrender, dass es sich lohnt, bis Eigenschaftserweiterungen existieren.

/// <summary>
/// Converts a given DateTime into a Unix timestamp
/// </summary>
/// <param name="value">Any DateTime</param>
/// <returns>The given DateTime in Unix timestamp format</returns>
public static int ToUnixTimestamp(this DateTime value)
{
    return (int)Math.Truncate((value.ToUniversalTime().Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}

/// <summary>
/// Gets a Unix timestamp representing the current moment
/// </summary>
/// <param name="ignored">Parameter ignored</param>
/// <returns>Now expressed as a Unix timestamp</returns>
public static int UnixTimestamp(this DateTime ignored)
{
    return (int)Math.Truncate((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}
Brad
quelle
2
Die Erweiterungsmethode ist eindeutig der richtige Weg, dies zu tun. Dies ist eine ausgezeichnete, ausgereifte Antwort - und ich verstehe nicht, warum es so wenige Stimmen gibt. Ich bin mir ziemlich sicher, dass Robba korrekt ist. Wenn Sie die Ausgabe als (int) umwandeln, wird das Ergebnis automatisch abgeschnitten. (Den Dezimalteil des Doppelten buchstäblich ignorieren).
Stephanie
4
(diese DateTime ignoriert) ist sehr, sehr irreführend
Lars Corneliussen
6

Wenn Sie 1970 von der aktuellen Zeit subtrahieren, beachten Sie, dass die Zeitspanne meistens ein Millisekundenfeld ungleich Null enthält. Wenn Sie aus irgendeinem Grund an den Millisekunden interessiert sind, denken Sie daran.

Folgendes habe ich getan, um dieses Problem zu umgehen.

 DateTime now = UtcNow();

 // milliseconds Not included.
 DateTime nowToTheSecond = new DateTime(now.Year,now.Month,now.Day,now.Hour,now.Minute,now.Second); 

 TimeSpan span = (date - new DateTime(1970, 1, 1, 0, 0, 0, 0));

 Assert.That(span.Milliseconds, Is.EqualTo(0)); // passes.
Kelly Anderson
quelle
5

Das benutze ich.

 public class TimeStamp
    {
        public Int32 UnixTimeStampUTC()
        {
            Int32 unixTimeStamp;
            DateTime currentTime = DateTime.Now;
            DateTime zuluTime = currentTime.ToUniversalTime();
            DateTime unixEpoch = new DateTime(1970, 1, 1);
            unixTimeStamp = (Int32)(zuluTime.Subtract(unixEpoch)).TotalSeconds;
            return unixTimeStamp;
        }
}
Matthew James Lewis
quelle
vielleicht machen es eine Erweiterungsmethode von DateTime
bizzehdee
3

Ich habe die elegantesten Ansätze für diese Dienstprogrammmethode zusammengefügt:

public static class Ux {
    public static decimal ToUnixTimestampSecs(this DateTime date) => ToUnixTimestampTicks(date) / (decimal) TimeSpan.TicksPerSecond;
    public static long ToUnixTimestampTicks(this DateTime date) => date.ToUniversalTime().Ticks - UnixEpochTicks;
    private static readonly long UnixEpochTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
}
XDS
quelle
2

Diese Lösung hat in meiner Situation geholfen:

   public class DateHelper {
     public static double DateTimeToUnixTimestamp(DateTime dateTime)
              {
                    return (TimeZoneInfo.ConvertTimeToUtc(dateTime) -
                             new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds;
              }
    }

Verwenden des Helfers im Code:

double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)
Aslan Kystaubayev
quelle
0

Es gibt eine ToUnixTimeMilliseconds für DateTimeOffset im System

Sie können eine ähnliche Methode für DateTime schreiben:

public static long ToUnixTimeSeconds(this DateTime value)
{
    return value.Ticks / 10000000L - 62135596800L;
}

10000000L - Konvertieren von Ticks in Sekunden

62135596800L - Konvertierung des 01.01.01 in den 01.01.1978

Es gibt kein Problem mit Utc und Lecks

Timur Lemeshko
quelle
0

Unten finden Sie eine 2-Wege-Erweiterungsklasse, die Folgendes unterstützt:

  • Zeitzonenlokalisierung
  • Eingabe \ Ausgabe in Sekunden oder Millisekunden.

Im Fall von OP ist die Verwendung:

DateTime.Now.ToUnixtime();

oder

DateTime.UtcNow.ToUnixtime();

Obwohl es eine direkte Antwort gibt, glaube ich, dass es besser ist, einen generischen Ansatz zu verwenden. Insbesondere, weil es höchstwahrscheinlich ein Projekt ist, das eine solche Konvertierung benötigt, werden diese Erweiterungen ohnehin auch benötigt, daher ist es besser, für alle dasselbe Tool zu verwenden.

    public static class UnixtimeExtensions
    {
        public static readonly DateTime UNIXTIME_ZERO_POINT = new DateTime(1970, 1, 1, 0, 0,0, DateTimeKind.Utc);

        /// <summary>
        /// Converts a Unix timestamp (UTC timezone by definition) into a DateTime object
        /// </summary>
        /// <param name="value">An input of Unix timestamp in seconds or milliseconds format</param>
        /// <param name="localize">should output be localized or remain in UTC timezone?</param>
        /// <param name="isInMilliseconds">Is input in milliseconds or seconds?</param>
        /// <returns></returns>
        public static DateTime FromUnixtime(this long value, bool localize = false, bool isInMilliseconds = true)
        {
            DateTime result;

            if (isInMilliseconds)
            {
                result = UNIXTIME_ZERO_POINT.AddMilliseconds(value);
            }
            else
            {
                result = UNIXTIME_ZERO_POINT.AddSeconds(value);
            }

            if (localize)
                return result.ToLocalTime();
            else
                return result;
        }

        /// <summary>
        /// Converts a DateTime object into a Unix time stamp
        /// </summary>
        /// <param name="value">any DateTime object as input</param>
        /// <param name="isInMilliseconds">Should output be in milliseconds or seconds?</param>
        /// <returns></returns>
        public static long ToUnixtime(this DateTime value, bool isInMilliseconds = true)
        {
            if (isInMilliseconds)
            {
                return (long)value.ToUniversalTime().Subtract(UNIXTIME_ZERO_POINT).TotalMilliseconds;
            }
            else
            {
                return (long)value.ToUniversalTime().Subtract(UNIXTIME_ZERO_POINT).TotalSeconds;
            }
        }
    }
SingleFlake
quelle
Achten Sie darauf, die Millisekunden- und Sekundenformate nicht zu verwechseln (der beste Fall ist eine Ausnahme, der schlechteste ist eine unlogische Konvertierung). Ich habe die Eingabe / Ausgabe standardmäßig auf das Millisekundenformat eingestellt. Wenn Sie das Sekundenformat standardmäßig verwenden möchten, ändern Sie einfach isInMilliseconds = true (in beiden Methoden) auf false.
SingleFlake
0

Ich habe dies verwendet, nachdem ich eine Weile gekämpft hatte. Es berücksichtigt auch den Zeitzonenversatz:

    public double Convert_DatTime_To_UNIXDATETIME(DateTime dt)
    {
        System.DateTime from_date = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
        double unix_time_since = dt.Subtract(from_date).TotalMilliseconds;

        TimeSpan ts_offset = TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);

        double offset = ts_offset.TotalMilliseconds;

        return unix_time_since - offset;
    }
Bruce Cameron
quelle
-1

Der einfache Code, den ich verwende:

public static long CurrentTimestamp()
{
   return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds * 1000);
}

Dieser Code gibt einen Unix-Zeitstempel an, insgesamt Millisekunden vom 01.01.1970 bis heute.

Erkin Eren
quelle