Cara mendapatkan cap waktu unix di C #

Jawaban:

597

Anda mendapatkan cap waktu unix dalam C # dengan menggunakan DateTime.UtcNowdan mengurangi waktu zaman 1970-01-01.

misalnya

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

DateTime.UtcNowdapat diganti dengan DateTimeobjek apa pun yang Anda inginkan untuk mendapatkan cap waktu unix.

Ada juga bidang, DateTime.UnixEpochyang sangat buruk didokumentasikan oleh MSFT, tetapi dapat menjadi penggantinew DateTime(1970, 1, 1)

bizzehdee
sumber
28
Mengomentari atas nama @wdhough. "Jawaban ini memiliki batasan dengan batas Int32 yang, saya percaya, 2.147.483.647. Menurut onlineconversion.com/unix_time.htm ini sama dengan waktu Sel, 19 Jan 2038 03:14:07 GMT Saya kira ada jenis nomor alternatif , dobel, panjang, dll akhirnya akan memiliki batas juga, tapi saya pikir itu layak disebut. Saya memilih lama di sini karena saya ingin seluruh nomor. Semoga ini bisa membantu "
IsmailS
11
Cap waktu unix secara tradisional bilangan bulat 32 bit, dan memiliki rentang '1970-01-01 00:00:01' UTC hingga '2038-01-19 03:14:07' UTC.
the_nuts
89
Gila bahwa konversi waktu UNIX tidak ada di perpustakaan standar sebagai bagian dari DateTime.
xingyu
7
Atau menggunakan integer arythmetic:DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
Anton Petrov
2
Datetime yang dikurangkan tidak perlu UTC?
jjxtra
573

Pada. NET 4.6, ada DateTimeOffset.ToUnixTimeSeconds().


Ini adalah metode instan, jadi Anda diharapkan menyebutnya sebagai instance dari DateTimeOffset. Anda juga dapat melakukan apapun DateTime, meskipun waspadai zona waktu .

Untuk mendapatkan cap waktu saat ini:

DateTimeOffset.UtcNow.ToUnixTimeSeconds()

Untuk mendapatkan cap waktu dari DateTime:

DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Bob
sumber
126
Baik.
Sudah
35
@MattBorja Untungnya, mengembalikan Int64- pada saat bergulir, kita tidak akan menggunakan Bumi lagi karena kekurangan Bumi.
Bob
24
Untuk orang lain yang bertanya-tanya, Anda bisa mendapatkan cap waktu saat ini denganDateTimeOffset.Now.ToUnixTimeSeconds()
kR105
8
@ Bizzehdee, Pun berniat?
st0le
5
Anda bisa mendapatkan UTC unixtimestamp dengan: DateTimeOffset.UtcNow.ToUnixTimeSeconds ()
Yair Levi
39

Anda juga dapat menggunakan Kutu. Saya sedang mengkode untuk Windows Mobile jadi tidak memiliki set lengkap metode. TotalSeconds tidak tersedia untuk saya.

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

atau

TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
TimeSpan unixTicks = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
double unixTime = unixTicks.TotalSeconds;
Dave Hindle
sumber
1
Kesalahan untuk solusi kedua: Tidak dapat mengonversi tipe sumber 'ganda' ke tipe target 'panjang'.
Pixar
@ Pixar: Sampel kedua sudah diperbaiki
JBert
5
new DateTime(1970, 1, 1)menciptakan waktu dengan Kindproperti yang tidak ditentukan . Apa yang Anda benar-benar ingin new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)menjadi benar
diasingkan
Dari .NET Core 2.1 Anda dapat menggunakan DateTime.UnixEpoch alih-alih DateTime baru (1970, 1, 1) lihat docs.microsoft.com/en-us/dotnet/api/…
Jaa H
27

Inilah yang saya gunakan:

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

Perlu diingat bahwa metode ini akan mengembalikan waktu sebagai Waktu Univeral Terkoordinasi (UTC).

Bartłomiej Mucha
sumber
(TotalSeconds memiliki doubletipe; casting terlalu lama akan menyebabkan hilangnya presisi.)
frankish
Anda benar, tapi kami tidak perlu khawatir tentang itu selama beberapa ribu tahun :)
Bartłomiej Mucha
21

Memotong .TotalSecondspenting karena didefinisikan sebagaithe value of the current System.TimeSpan structure expressed in whole fractional seconds.

Dan bagaimana dengan ekstensi DateTime? Yang kedua mungkin lebih membingungkan bahwa nilainya sampai ekstensi properti ada.

/// <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
sumber
2
Metode penyuluhan jelas merupakan cara untuk melakukan ini dengan rapi. Ini adalah jawaban yang sangat baik dan matang - dan saya tidak mengerti mengapa ia memiliki begitu sedikit suara. Cukup yakin bahwa Robba benar - casting output sebagai (int) secara otomatis memotong hasilnya. (Secara harfiah mengabaikan bagian desimal ganda).
Stephanie
4
(DateTime ini diabaikan) sangat, sangat menyesatkan
Lars Corneliussen
6

Saat Anda mengurangi 1970 dari waktu saat ini, ketahuilah bahwa rentang waktu akan paling sering memiliki bidang bukan nol milidetik. Jika karena alasan tertentu Anda tertarik dengan milidetik, ingatlah ini.

Inilah yang saya lakukan untuk mengatasi masalah ini.

 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
sumber
5

Inilah yang saya gunakan.

 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
sumber
mungkin menjadikannya metode ekstensi DateTime
bizzehdee
3

Saya telah menyatukan pendekatan yang paling elegan untuk metode utilitas ini:

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
sumber
2

Solusi ini membantu dalam situasi saya:

   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;
              }
    }

menggunakan kode pembantu:

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

Ada ToUnixTimeMilliseconds untuk DateTimeOffset di Sistem

Anda dapat menulis metode serupa untuk DateTime:

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

10000000L - mengonversi kutu ke detik

62135596800L - mengkonversi 01.01.01 ke 01.01.1978

Tidak ada masalah dengan Utc dan kebocoran

Timur Lemeshko
sumber
0

Di bawah ini adalah kelas ekstensi 2 arah yang mendukung:

  • Lokalisasi zona waktu
  • Input \ output dalam detik atau milidetik.

Dalam kasus OP, penggunaannya adalah:

DateTime.Now.ToUnixtime();

atau

DateTime.UtcNow.ToUnixtime();

Meskipun ada jawaban langsung, saya percaya menggunakan pendekatan generik lebih baik. Terutama karena kemungkinan besar proyek yang memerlukan konversi seperti ini, juga akan memerlukan ekstensi ini, jadi lebih baik menggunakan alat yang sama untuk semua.

    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
sumber
Berhati-hatilah untuk tidak membingungkan format milidetik dan detik (kasus terbaik adalah perkecualian, yang terburuk adalah konversi tidak logis) Saya sudah default input \ output ke format milidetik. Jika Anda lebih suka menggunakan format detik sebagai default, cukup alihkan isInMilliseconds = true (dalam kedua metode) ke false.
SingleFlake
0

Saya menggunakan ini setelah berjuang untuk sementara waktu, itu juga melayani zona waktu:

    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
sumber
-1

Kode sederhana yang saya gunakan:

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

Kode ini memberikan cap waktu unix, total milidetik dari 1970-01-01 hingga sekarang.

Erkin Eren
sumber