आप C # में युग परिवर्तन कैसे करते हैं?


377

आप यूनिक्स युग को C # में वास्तविक समय में कैसे परिवर्तित करते हैं ? (युग की शुरुआत 1/1/1970)


1
जब तक मैं कुछ याद नहीं कर रहा हूँ, "युग" केवल एक विशेष टाइमकीपिंग योजना का मूल बिंदु है। उदाहरणों में 1/1/0001, 1/1/1970 और 1/1/2000 शामिल हैं। यह एक योजना के बजाय एक योजना की विशेषता का अधिक है (उदाहरण के लिए, जूलियन) ही।
बॉब कॉफमैन

8
1 जनवरी, 1970 के बाद से यूकोच का समय सेकंड की संख्या है।
टेलर लेसे

13
@ टेलर यह यूनिक्स समय के लिए युग है, और यह शायद सही है, लेकिन यह एकमात्र वैध युग नहीं है। यूनिक्स समय उपयोगकर्ताओं को उस बिंदु पर खुद को भ्रमित नहीं करना चाहिए।
जोएल कोएहॉर्न

अन्य जवाबों के साथ
डुप्लीकेट

जवाबों:


563

मुझे लगता है कि आप यूनिक्स समय का मतलब है , जो 1 जनवरी 1970 को आधी रात (UTC) के बाद से सेकंड की संख्या के रूप में परिभाषित किया गया है।

public static DateTime FromUnixTime(long unixTime)
{
    return epoch.AddSeconds(unixTime);
}
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

74
इसे सही ढंग से काम करने के लिए मुझे बदलना पड़ा। .AddSeconds to .AddMilliseconds। आपको यह जानना होगा कि आपका नंबर सही परिणाम प्राप्त करने के लिए सेकंड या मिलिसेकंड से आ रहा है या नहीं। उदाहरण के लिए निम्न तिथि: 1406310305188 (25 जुलाई 2014)। epochconverter.com आपको अपने रूपांतरण परिणामों की जांच करने देगा।
16

5
आपको या तो पैरामीटर प्रकार को डबल में बदलना चाहिए (क्योंकि AddSeconds डबल स्वीकार करता है और इसलिए डबल डाउनकास्ट करेगा) या विधि वर्णन में एक अस्वीकरण जोड़ें जो कि तर्क में 64 बिट्स में से केवल 53 को संरक्षित किया जाएगा।
टोमोसियस

6
@jrandomuser: यूनिक्स युग के समय को पारंपरिक रूप से सेकंड के रूप में प्रतिनिधित्व किया जाता है । इसका इस्तेमाल करने के बनने के बाद से आम है मिलीसेकेंड युग (उदाहरण के लिए, जावास्क्रिप्ट) के बाद से, लेकिन क्लासिक परिभाषा सेकंड है। निचला-रेखा, बस यह जान लें कि आपका इनपुट मान क्या है (सेकंड, मिलीसेकंड, टिक, जो भी हो) और सही AddXYZविधि का उपयोग करें ।
टीजे क्राउडर

पहले AddMilliseconds के साथ प्रयास करें और यदि वर्ष अभी भी 1970 है तो AddSeconds करें। इस तरह यह हर समय मिलिसेकंड या सेकंड के बारे में चिंता किए बिना काम करेगा। साथ ही आप एक अतिप्रवाह उत्तेजना को रोक सकते हैं। AddSeconds में बड़ी संख्या में पास होने से कोड क्रैश हो जाएगा
टोनो नाम

213

.Net (v4.6) का नवीनतम संस्करण यूनिक्स समय रूपांतरणों के लिए बिल्ट-इन समर्थन में जोड़ा गया है। इसमें यूनिक्स समय से लेकर सेकंड या मिली सेकेंड तक, दोनों शामिल हैं।

  • सेकंड में यूनिक्स समय DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
  • DateTimeOffset सेकंड में यूनिक्स समय:

long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
  • मिलीसेकंड में यूनिक्स समय DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
  • DateTimeOffset मिलीसेकंड में यूनिक्स समय:

long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();

नोट: ये विधियाँ और से परिवर्तित होती हैं DateTimeOffset। एक DateTimeप्रतिनिधित्व प्राप्त करने के लिए बस DateTimeOffset.DateTimeसंपत्ति का उपयोग करें :

DateTime dateTime = dateTimeOffset.UtcDateTime;

1
मुझे मिल रहा है 'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'मैं इसे कैसे हल करूंगा?
हैप्पी बर्ड

@HappyBird क्या आप .NET 4.6 या इससे ऊपर के हैं?
i3arnon

एक ही बात - 4.7.2 और DateTimeOffset के लिए कोई FromUnixTimeMilliseconds विधि नहीं है ...
मिखाइल_सम

मैं समझ गया। मुझे नई वस्तु बनाने की आवश्यकता नहीं है। यह एक स्थिर विधि है।
मिखाइल_सम ०

मुझे पहली नज़र में डिफ़ॉल्ट मान थोड़ा उलझा हुआ लगा। मिल 1000 से सेकंड में परिवर्तित करने के लिए Bc 1000 कारक है।
ब्ल्यू

169

ल्यूक को सभी श्रेय के साथ, मैंने आसान उपयोग के लिए कुछ विस्तार विधियों को एक साथ रखा है:

public static DateTime FromUnixTime(this long unixTime)
{
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    return epoch.AddSeconds(unixTime);
}

public static long ToUnixTime(this DateTime date)
{
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    return Convert.ToInt64((date - epoch).TotalSeconds);
}

CodesInChaos से नीचे टिप्पणी ध्यान दें कि ऊपर FromUnixTimeरिटर्न एक DateTimeएक के साथ Kindकी Utcहै, जो ठीक है, लेकिन इसके बाद के संस्करण ToUnixTimeभी बहुत कुछ संदिग्ध है कि में की तरह क्या के लिए खाते में नहीं है DateTimeदिए गए dateहै। के लिए अनुमति देने के लिए dateकी Kindजा रही है या तो Utcया Local, उपयोग ToUniversalTime:

public static long ToUnixTime(this DateTime date)
{
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds);
}

ToUniversalTimeएक में परिवर्तित कर देंगे Local(या Unspecified) DateTimeके लिए Utc

अगर आप युगांतर दिनांक बनाने के लिए नहीं चाहते हैं तो दिनांक समय से आगे बढ़ते समय युगांतर आप भी कर सकते हैं:

public static long ToUnixTime(this DateTime date)
{
    return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}

6
ToUnixTimeकेवल तभी सही ढंग से काम करता है जब Utc में तारीख होती है। या तो एक चेक जोड़ें, या इसे रूपांतरित करें। (व्यक्तिगत रूप से मैं चेक पसंद करता हूं)
कोडइन्चोस

2
बस पिछले घंटे खर्च क्यों यह काम नहीं करता है। आप में काम करने की जरूरत है milliseconds नहीं सेकंड !!!
क्रिस्टियान बी

7
@ क्रिश्चियनबी: "यूनिक्स समय" परंपरागत रूप से सेकंड है, न कि मिलीसेकंड, द एपॉच के बाद से, हालांकि इन दिनों मैं यह जांचने के लिए सावधान हूं कि कोई परिभाषा क्या उपयोग कर रहा है। सेकंड्स काफी अच्छा हुआ करते थे, और हमें हस्ताक्षरित 32-बिट मूल्यों में द एपोच के दोनों ओर एक उचित सीमा प्रदान की। (और यही कारण है कि १ ९ जनवरी २०३T को ३:१४ बजे के बाद जीएमटी कुछ के लिए बुरा समय हो सकता है ...) मिलीसेकंड का उपयोग करना एक अधिक आधुनिक अभ्यास है जो हमारे नियमित रूप से ६४-बिट मान (दोनों अभिन्न) को फेंकने में सक्षम है। और डबल परिशुद्धता IEEE-754) ...
TJ Crowder

5
कोड के लिए धन्यवाद। एपोच बेस बनाते समय बस थोड़ी सी सिफारिश: स्पष्ट रूप से मिलिसकॉन्ड मान को 0. पर सेट करना सुनिश्चित करें। * s * /, 0 / * ms * /, DateTimeKind.Utc); यदि आप स्पष्ट रूप से इसे निर्धारित नहीं करते हैं तो मिलीसेकंड मान 1 के रूप में सामने आता है। इससे मेरे परीक्षणों में कुछ विसंगतियां हुईं।
ctrlplusb

1
आपको उपयोग करना चाहिए AddMillisecondsऔर आपको डबल नॉट फ्लोट का उपयोग करना चाहिए। अन्यथा आप गलत समय के साथ समाप्त हो जाएंगे।
एक्सल

25

आप वास्तव में AddMilliseconds (मिलीसेकंड) चाहते हैं, सेकंड नहीं। सेकंड जोड़ने से आप सीमा से बाहर हो जाएंगे।


ऐसा क्यों है? epochconverter.com यह कहता है कि आप 1/1/970 के बाद से सेकंड की संख्या पर जोड़ते हैं एमएस नहीं।
जेमी आर रिटलेवस्की

यदि आप एमएस से जा रहे हैं तो आप स्पष्ट रूप से चाहते हैं AddMillisऔर यदि आप सेकंड से शुरू कर रहे हैं तो आप स्पष्ट रूप से चाहते हैं AddSeconds
जूता

मुझे वही समस्या थी जो मैं सेकंड का उपयोग करते समय सीमा से बाहर हो रहा था। जिस यूनिक्स समय को मैं बदलने की कोशिश कर रहा था वह मिलीसेकंड में था। मुझे लगा कि यह सेकंड में था। मुझे लगता है कि कुछ यूनिक्स समय को मील के पत्थर में मापा जाता है।
डूडलकाणा

यूनिक्स समय आमतौर पर सेकंड में व्यक्त किया जाता है, लेकिन 0.001 सेकंड (= 1 एमएस) की एक वैध संख्या है। जब संदेह हो, तो बस अधिकतम संभव परिशुद्धता का उपयोग करें।
स्कॉट

9

यदि आप बेहतर प्रदर्शन चाहते हैं तो आप इस संस्करण का उपयोग कर सकते हैं।

public const long UnixEpochTicks = 621355968000000000;
public const long TicksPerMillisecond = 10000;
public const long TicksPerSecond = TicksPerMillisecond * 1000;

//[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static DateTime FromUnixTimestamp(this long unixTime)
{
    return new DateTime(UnixEpochTicks + unixTime * TicksPerSecond);
}

Net471 के तहत एक त्वरित बेंचमार्क (बेंचमार्कडॉटनेट) से मुझे यह संख्या मिलती है:

        Method |     Mean |     Error |    StdDev | Scaled |
-------------- |---------:|----------:|----------:|-------:|
         LukeH | 5.897 ns | 0.0897 ns | 0.0795 ns |   1.00 |
      MyCustom | 3.176 ns | 0.0573 ns | 0.0536 ns |   0.54 |

ल्यूक के संस्करण के खिलाफ तेजी से 2x (यदि प्रदर्शन मैटर करता है)

यह आंतरिक रूप से DateTime के कार्य करने के तरीके के समान है।


9

विधि का उपयोग करें DateTimeOffset.ToUnixTimeMilliseconds () यह 1970-01-01T00: 00: 00.000Z के बाद से समाप्त हो चुके मिलीसेकंड की संख्या देता है।

यह केवल फ्रेमवर्क 4.6 या उच्चतर के साथ समर्थित है

var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

यह अच्छी तरह से यहाँ DateTimeOffset.ToUnixTimeMilliseconds दस्तावेज है

दूसरा तरीका निम्न का उपयोग करना है

long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;

सेकंड के साथ © पाने के लिए केवल आप उपयोग कर सकते हैं

 var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;

और निम्न विधि Epochसे परिवर्तित करेंDateTime

private DateTime Epoch2UTCNow(int epoch) 
{
    return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch); 
}

DateTime.Ticks - प्रत्येक टिक "एक सौ नैनोसेकंड" है, जो इसे याद रखने के लिए एक अतिरिक्त 'चीज' बनाता है। यदि दोनों को छोड़ दें .Ticks, तो किसी को DateTime के विकल्प से एक अच्छा TimeSpan उदाहरण मिलेगा।
user2864740

8
// convert datetime to unix epoch seconds
public static long ToUnixTime(DateTime date)
{
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds);
}

DateTime ऑब्जेक्ट के लिए ToUniversalTime () का उपयोग करना चाहिए।


5

मैं युग परिवर्तन के लिए निम्नलिखित विस्तार विधियों का उपयोग करता हूं

public static int GetEpochSeconds(this DateTime date)
    {
        TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
        return (int)t.TotalSeconds;
    }

public static DateTime FromEpochSeconds(this DateTime date, long EpochSeconds)
    {
        var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        return epoch.AddSeconds(EpochSeconds);

    }

2

केवल मिलिसेकंड या सेकंड का उपयोग करने के बारे में चिंता न करें:

    public static DateTime _ToDateTime(this long unixEpochTime)
    {
        DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        var date = epoch.AddMilliseconds(unixEpochTime);

        if (date.Year > 1972)
            return date;

        return epoch.AddSeconds(unixEpochTime);
    }

यदि युग का समय सेकंडों में है, तो ऐसा कोई तरीका नहीं है जिससे आप वर्ष 1972 को मिलीसेकंड में जोड़ सकें।


1

यदि आप 4.6 का उपयोग नहीं कर रहे हैं, तो यह स्रोत की मदद कर सकता है : System.IdentityModel.Tokens

    /// <summary>
    /// DateTime as UTV for UnixEpoch
    /// </summary>
    public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);

    /// <summary>
    /// Per JWT spec:
    /// Gets the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the desired date/time.
    /// </summary>
    /// <param name="datetime">The DateTime to convert to seconds.</param>
    /// <remarks>if dateTimeUtc less than UnixEpoch, return 0</remarks>
    /// <returns>the number of seconds since Unix Epoch.</returns>
    public static long GetIntDate(DateTime datetime)
    {
        DateTime dateTimeUtc = datetime;
        if (datetime.Kind != DateTimeKind.Utc)
        {
            dateTimeUtc = datetime.ToUniversalTime();
        }

        if (dateTimeUtc.ToUniversalTime() <= UnixEpoch)
        {
            return 0;
        }

        return (long)(dateTimeUtc - UnixEpoch).TotalSeconds;
    }    

JWT से उदाहरण के लिए धन्यवाद। वैसे, इसका इस्तेमाल करने के लिए, बस का उपयोग करें: using Microsoft.IdentityModel.Tokens; ... EpochTime.GetIntDate(dateTime);
liquide

0

मामले में आप एक बदलने की आवश्यकता timeval struct (सेकंड, माइक्रोसेकंड) युक्त UNIX timeकरने के लिए DateTimeसटीक खोने के बिना, यह कैसे है:

DateTime _epochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private DateTime UnixTimeToDateTime(Timeval unixTime)
{
    return _epochTime.AddTicks(
        unixTime.Seconds * TimeSpan.TicksPerSecond +
        unixTime.Microseconds * TimeSpan.TicksPerMillisecond/1000);
}


-4

यहाँ मेरा समाधान है:

public long GetTime()
{
    DateTime dtCurTime = DateTime.Now.ToUniversalTime();

    DateTime dtEpochStartTime = Convert.ToDateTime("1/1/1970 0:00:00 AM");

    TimeSpan ts = dtCurTime.Subtract(dtEpochStartTime);

    double epochtime;

    epochtime = ((((((ts.Days * 24) + ts.Hours) * 60) + ts.Minutes) * 60) + ts.Seconds);   

    return Convert.ToInt64(epochtime);
}

7
क्या यह लीप वर्ष और लीप सेकंड आदि के लिए है?
जोदरेल

1
पिछली टिप्पणी पर विस्तार करने के लिए, यहां एक छोटा वीडियो है जो बताता है कि समय क्यों जटिल है और आपको इसे स्वयं करने का प्रयास क्यों नहीं करना चाहिए: youtube.com/watch?v=-5wpm-gesOY
vmrob
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.