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)


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

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;

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).


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

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.

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

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

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)

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



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

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

-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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.