คุณจะแปลงเวลายุค Unix เป็นเวลาจริงใน C # ได้อย่างไร (เริ่มตั้งแต่ 1/1/1970)
คุณจะแปลงเวลายุค Unix เป็นเวลาจริงใน C # ได้อย่างไร (เริ่มตั้งแต่ 1/1/1970)
คำตอบ:
ฉันคิดว่าคุณหมายถึงเวลา Unixซึ่งถูกกำหนดให้เป็นจำนวนวินาทีตั้งแต่เที่ยงคืน (UTC) ในวันที่ 1 มกราคม 1970
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);
AddXYZ
วิธีการที่เหมาะสม
รุ่นล่าสุดของสุทธิ (v4.6)เพียงแค่เพิ่มการสนับสนุนในตัวสำหรับการแปลงเวลายูนิกซ์ ซึ่งรวมถึงเวลาทั้งจากและเวลา Unix ที่แสดงด้วยวินาทีหรือมิลลิวินาที
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
ถึงเวลา Unix ในไม่กี่วินาที:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
ถึงเวลา Unix เป็นมิลลิวินาที:long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
หมายเหตุ: DateTimeOffset
วิธีการเหล่านี้แปลงไปและกลับจาก ในการรับการเป็นDateTime
ตัวแทนเพียงใช้DateTimeOffset.DateTime
คุณสมบัติ:
DateTime dateTime = dateTimeOffset.UtcDateTime;
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'
ฉันจะแก้ไขปัญหานี้อย่างไร
ด้วยเครดิตทั้งหมดถึงลุคฉันได้รวบรวมวิธีการขยายไว้ใช้งานง่าย:
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
's 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
เพื่อ
หากคุณไม่ต้องการสร้างอินสแตนซ์ยุคสมัยเมื่อย้ายจาก DateTime ไปยังยุคคุณยังสามารถทำได้:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
ToUnixTime
ทำงานได้อย่างถูกต้องหากวันที่อยู่ใน Utc เพิ่มการตรวจสอบหรือแปลง (โดยส่วนตัวแล้วฉันชอบเช็ค)
milliseconds
ไม่กี่วินาที !!!
AddMilliseconds
และคุณควรใช้ Double NOT Float มิฉะนั้นคุณจะจบลงด้วยเวลาที่ผิด
คุณต้องการ AddMilliseconds (มิลลิวินาที) ไม่ใช่วินาที การเพิ่มวินาทีจะทำให้คุณมีข้อยกเว้นนอกช่วง
AddMillis
AddSeconds
หากคุณต้องการประสิทธิภาพที่ดีขึ้นคุณสามารถใช้เวอร์ชันนี้ได้
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);
}
จากการวัดประสิทธิภาพอย่างรวดเร็ว (BenchmarkDotNet) ภายใต้ 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 |
เร็วขึ้น 2 เท่าเมื่อเทียบกับเวอร์ชั่นของ LukeH (หากมีประสิทธิภาพ)
ซึ่งคล้ายกับการทำงานของ DateTime ภายใน
ใช้วิธีDateTimeOffset.ToUnixTimeMilliseconds () มันคืนค่าจำนวนมิลลิวินาทีที่ผ่านไปตั้งแต่ 1970-01-01T00: 00: 00.000Z
รองรับเฉพาะกับ Framework 4.6 หรือสูงกว่าเท่านั้น
var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
มันบันทึกไว้ที่นี่ดี DateTimeOffset.ToUnixTimeMilliseconds
อีกวิธีคือการใช้ต่อไปนี้
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
ในการรับ EPOCH ภายในไม่กี่วินาทีคุณสามารถใช้งานได้
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);
}
.Ticks
จะได้รับอินสแตนซ์ของ TimeSpan ที่ดีจากการลบวันที่และเวลา
// 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);
}
ควรใช้ ToUniversalTime () สำหรับวัตถุ DateTime
ฉันใช้วิธีการต่อไปนี้สำหรับการแปลงยุค
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);
}
หากไม่ต้องกังวลกับการใช้มิลลิวินาทีหรือวินาทีให้ทำดังนี้
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 เพิ่มมิลลิวินาที
หากคุณไม่ได้ใช้ 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;
}
using Microsoft.IdentityModel.Tokens; ... EpochTime.GetIntDate(dateTime);
ในกรณีที่คุณต้องการแปลงstruct timeval (วินาที microseconds) ที่มี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);
}
ตั้งแต่. Net 4.6 ขึ้นไปโปรดใช้ DateTimeOffset.Now.ToUnixTimeSeconds ()
นี่คือทางออกของฉัน:
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);
}