วิธีรับการประทับเวลา unix ใน C #


398

ฉันได้ดู stackoverflow แล้วและยังดูคำถามที่แนะนำบางคำถามและดูเหมือนไม่มีคำตอบคุณจะได้รับ unix timestamp ใน C # ได้อย่างไร


คำตอบ:


597

คุณจะได้รับการประทับเวลา unix ใน C # โดยการใช้DateTime.UtcNowและลบเวลาของยุค 1970-01-01

เช่น

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

DateTime.UtcNowสามารถถูกแทนที่ด้วยDateTimeวัตถุใด ๆที่คุณต้องการรับการประทับเวลา unix สำหรับ

นอกจากนี้ยังมีฟิลด์DateTime.UnixEpochซึ่งMSFT มีเอกสารไม่ดีมากแต่อาจใช้แทนได้new DateTime(1970, 1, 1)


28
แสดงความคิดเห็นในนามของ @wdhough "คำตอบนี้มีข้อ จำกัด เกี่ยวกับขีด จำกัด ของ Int32 ซึ่งก็คือฉันเชื่อว่า 2,147,483,647 อ้างอิงจากonlineconversion.com/unix_time.htmนี่เท่ากับเวลาของอ., 19 ม.ค. 2038 03:14:07 GMT ท้ายที่สุดยาว ฯลฯ ก็จะมีขีด จำกัด เช่นกัน แต่ฉันคิดว่ามันควรค่าแก่การพูดถึงฉันเลือกที่นี่เพราะฉันต้องการจำนวนเต็มหวังว่านี่จะช่วยได้ "
IsmailS

11
การประทับเวลา unix นั้นเป็นจำนวนเต็ม 32 บิตและมีช่วง '1970-01-01 00:00:01' UTC ถึง '2038-01-19 03:14:07' UTC
the_nuts

89
เป็นเรื่องที่แย่ที่การแปลงเวลา UNIX ไม่ได้อยู่ในไลบรารีมาตรฐานซึ่งเป็นส่วนหนึ่งของ DateTime
xingyu

7
หรือใช้ arythmetic จำนวนเต็ม:DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
Anton Petrov

2
เวลาที่ใช้ในการลบไม่จำเป็นต้องเป็น UTC?
jjxtra

570

ในฐานะของ .NET 4.6 DateTimeOffset.ToUnixTimeSeconds()มี


DateTimeOffsetนี่คือวิธีการเช่นเพื่อให้คุณคาดว่าจะเรียกมันว่าในตัวอย่างของ คุณยังสามารถส่งตัวอย่างของการใด ๆDateTimeแต่ระวังเขตเวลา

วิธีรับเวลาประทับปัจจุบัน:

DateTimeOffset.UtcNow.ToUnixTimeSeconds()

วิธีรับการประทับเวลาจากDateTime:

DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();

126
ดี. มันเกี่ยวกับเวลา
bizzehdee

35
@MattBorja โชคดีที่มันกลับมาInt64- ตามเวลาที่ผ่านไปเราจะไม่ใช้โลกเป็นเวลาหลายปีอีกต่อไปสำหรับการขาดโลก
Bob

24
สำหรับคนอื่นที่สงสัยคุณสามารถรับการประทับเวลาปัจจุบันด้วยDateTimeOffset.Now.ToUnixTimeSeconds()
kR105

8
@bizzehdee, Pun ตั้งใจหรือไม่
st0le

5
คุณสามารถรับ UTC unixtimestamp ด้วย: DateTimeOffset.UtcNow.ToUnixTimeSeconds ()
Yair Levi

39

คุณยังสามารถใช้เห็บ ฉันกำลังเขียนโค้ดสำหรับ Windows Mobile จึงไม่มีวิธีการเต็มรูปแบบ TotalSecondsไม่สามารถใช้ได้สำหรับฉัน

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

หรือ

TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
TimeSpan unixTicks = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
double unixTime = unixTicks.TotalSeconds;

1
ข้อผิดพลาดสำหรับโซลูชันที่สอง: ไม่สามารถแปลงประเภทแหล่งที่มา 'คู่' เป็นประเภทเป้าหมาย 'ยาว'
Pixar

@Pixar: ตัวอย่างที่สองได้รับการแก้ไข
JBert

5
new DateTime(1970, 1, 1)สร้างเวลาด้วยKindคุณสมบัติที่ไม่ระบุ สิ่งที่คุณต้องการnew DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)จะแก้ไขให้ถูกต้องจริง ๆ
กระทบ

จาก. NET Core 2.1 คุณสามารถใช้ DateTime.UnixEpoch แทน DateTime ใหม่ (1970, 1, 1) ดูdocs.microsoft.com/en-us/dotnet/api/…
Jaa H

27

นี่คือสิ่งที่ฉันใช้:

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

โปรดทราบว่าวิธีนี้จะส่งคืนเวลาเป็น Coordinated Univeral Time (UTC)


(TotalSeconds มีdoubleประเภทหล่อมันยาวจะทำให้เกิดการสูญเสียของความแม่นยำ.)
ส่ง

คุณพูดถูก แต่เราไม่ต้องกังวลเกี่ยวกับเรื่องนี้เป็นเวลาหลายพันปี :)
Bartłomiej Mucha

21

การตัดทอน.TotalSecondsมีความสำคัญเนื่องจากถูกกำหนดให้เป็นthe value of the current System.TimeSpan structure expressed in whole fractional seconds.

และวิธีการเกี่ยวกับการขยายDateTimeหรือไม่ ส่วนที่สองอาจสร้างความสับสนมากกว่าว่ามีค่าจนกว่าส่วนขยายคุณสมบัติจะมีอยู่

/// <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
วิธีการขยายเป็นวิธีที่ชัดเจนในการทำสิ่งนี้อย่างชัดเจน นี่เป็นคำตอบที่ยอดเยี่ยมและเป็นผู้ใหญ่ - และฉันไม่เข้าใจว่าทำไมมันถึงมีคะแนนเสียงน้อยมาก ค่อนข้างแน่ใจว่า Robba นั้นถูกต้องแล้ว - ส่งเอาต์พุตเป็น (int) ตัดทอนผลลัพธ์โดยอัตโนมัติ (ไม่สนใจส่วนทศนิยมของ double)
สเตฟานี

4
(วันที่เวลานี้เพิกเฉย) เป็นสิ่งที่สร้างความเข้าใจผิดอย่างมาก
Lars Corneliussen

6

เมื่อคุณลบ 1970 จากเวลาปัจจุบันโปรดทราบว่าช่วงเวลาที่มักจะมีฟิลด์ที่ไม่ใช่ศูนย์มิลลิวินาที หากคุณมีความสนใจในมิลลิวินาทีด้วยเหตุผลบางประการ

นี่คือสิ่งที่ฉันทำเพื่อแก้ไขปัญหานี้

 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

นี่คือสิ่งที่ฉันใช้

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

อาจทำให้เป็นวิธีการเสริมของ DateTime
bizzehdee

3

ฉันเชื่อมต่อกันด้วยวิธีที่สวยงามที่สุดในวิธีการยูทิลิตี้นี้:

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

โซลูชันนี้ช่วยในสถานการณ์ของฉัน:

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

ใช้ผู้ช่วยในรหัส:

double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)

0

มี ToUnixTimeMilliseconds สำหรับ DateTimeOffset ในระบบ

คุณสามารถเขียนวิธีที่คล้ายกันสำหรับ DateTime:

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

10,000000L - การแปลงเห็บเป็นวินาที

62135596800L - แปลง 01.01.01 ถึง 01.01.1978

ไม่มีปัญหากับ Utc และการรั่วไหล



0

ด้านล่างเป็นคลาสส่วนขยายแบบ 2 ทิศทางที่รองรับ:

  • การแปลเขตเวลา
  • อินพุต \ เอาต์พุตในไม่กี่วินาทีหรือมิลลิวินาที

ในกรณีของ OP การใช้งานคือ:

DateTime.Now.ToUnixtime();

หรือ

DateTime.UtcNow.ToUnixtime();

แม้ว่าจะมีคำตอบโดยตรง แต่ฉันเชื่อว่าการใช้วิธีการทั่วไปนั้นดีกว่า โดยเฉพาะอย่างยิ่งเนื่องจากเป็นไปได้ว่าโครงการที่ต้องการการแปลงเช่นนี้จะต้องมีส่วนขยายเหล่านี้ด้วยดังนั้นจึงควรใช้เครื่องมือเดียวกันสำหรับทุกคน

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

ระวังอย่าสับสนรูปแบบมิลลิวินาทีและวินาที (กรณีที่ดีที่สุดคือข้อยกเว้นการแปลงที่ไม่สมเหตุผลที่เลวร้ายที่สุด) ฉันได้ตั้งค่าเริ่มต้น input \ output เป็นรูปแบบมิลลิวินาที หากคุณต้องการใช้รูปแบบวินาทีเป็นค่าเริ่มต้นเพียงเปลี่ยน isInMilliseconds = true (ทั้งสองวิธี) เป็นเท็จ
SingleFlake

0

ฉันใช้สิ่งนี้หลังจากดิ้นรนไประยะหนึ่งแล้วมันก็สำคัญกับเขตเวลาชดเชยเช่นกัน:

    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

รหัสง่าย ๆ ที่ฉันใช้:

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

รหัสนี้จะให้การประทับเวลายูนิกซ์รวมเป็นมิลลิวินาทีจาก1970-01-01ถึงตอนนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.