Làm thế nào để bạn chuyển đổi thời gian epoch Unix thành thời gian thực trong C #? (Kỷ nguyên bắt đầu 1/1/1970)
Làm thế nào để bạn chuyển đổi thời gian epoch Unix thành thời gian thực trong C #? (Kỷ nguyên bắt đầu 1/1/1970)
Câu trả lời:
Tôi đoán rằng bạn có nghĩa là thời gian Unix , được định nghĩa là số giây kể từ nửa đêm (UTC) vào ngày 1 tháng 1 năm 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
phương pháp.
Các phiên bản mới nhất của Net (v4.6) chỉ thêm vào built-in hỗ trợ cho chuyển đổi thời gian Unix. Điều đó bao gồm cả đến và từ thời gian Unix được biểu thị bằng giây hoặc mili giây.
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
đến thời gian Unix tính bằng giây:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
đến thời gian Unix tính bằng mili giây:long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
Lưu ý: Các phương thức này chuyển đổi sang và từ DateTimeOffset
. Để có được một DateTime
đại diện chỉ cần sử dụng DateTimeOffset.DateTime
tài sản:
DateTime dateTime = dateTimeOffset.UtcDateTime;
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'
Làm thế nào tôi sẽ giải quyết vấn đề này?
Với tất cả tín dụng cho LukeH, tôi đã kết hợp một số phương thức mở rộng để dễ sử dụng:
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);
}
Lưu ý những nhận xét dưới đây từ CodesInChaos rằng ở trên FromUnixTime
lợi nhuận một DateTime
với một Kind
số Utc
, đó là tốt, nhưng ở trên ToUnixTime
là nhiều nghi ngờ trong đó không tính đến những loại DateTime
GIVEN date
là. Để cho phép date
của Kind
con người trong hai Utc
hoặc Local
, sử dụng 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
sẽ chuyển đổi một Local
(hoặc Unspecified
) DateTime
thành Utc
.
nếu bạn không muốn tạo phiên bản DateTime epoch khi chuyển từ DateTime sang epoch, bạn cũng có thể thực hiện:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
ToUnixTime
chỉ hoạt động chính xác nếu ngày ở Utc. Hoặc thêm một kiểm tra, hoặc chuyển đổi nó. (Cá nhân tôi thích kiểm tra hơn)
milliseconds
không vài giây !!!
AddMilliseconds
và bạn nên sử dụng Double NOT Float. Nếu không, bạn sẽ kết thúc với một thời gian sai.
Bạn thực sự muốn AddMilliseconds (mili giây), không phải giây. Thêm giây sẽ cho bạn một ngoại lệ ngoài phạm vi.
AddMillis
và nếu bạn đang bắt đầu từ giây bạn muốn rõ ràng AddSeconds
.
Nếu bạn muốn hiệu suất tốt hơn, bạn có thể sử dụng phiên bản này.
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);
}
Từ điểm chuẩn nhanh (BenchmarkDotNet) trong net471 tôi nhận được số này:
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 |
Nhanh hơn gấp 2 lần so với phiên bản của LukeH (nếu phương tiện hiệu suất)
Điều này tương tự như cách hoạt động của DateTime trong nội bộ.
Sử dụng phương thức DateTime Offerset.ToUnixTimeMilliseconds () Nó trả về số mili giây đã trôi qua kể từ 1970-01-01T00: 00: 00.000Z.
Điều này chỉ được hỗ trợ với Khung 4.6 trở lên
var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
Nó cũng được ghi lại ở đây DateTime Offerset.ToUnixTimeMilliseconds
Cách khác là sử dụng như sau
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
Để nhận EPOCH chỉ trong vài giây, bạn chỉ có thể sử dụng
var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
và chuyển đổi Epoch
sang DateTime
phương thức sau
private DateTime Epoch2UTCNow(int epoch)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch);
}
.Ticks
, người ta sẽ lấy lại một cá thể TimeSpan đẹp từ cơ chế DateTime.
Tôi sử dụng các phương thức mở rộng sau đây để chuyển đổi kỷ nguyên
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);
}
Để không lo lắng về việc sử dụng mili giây hoặc giây chỉ cần làm:
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);
}
Nếu thời gian kỷ nguyên tính bằng giây thì không có cách nào bạn có thể vượt qua năm 1972 thêm mili giây.
Nếu bạn không sử dụng 4.6, điều này có thể giúp Nguồn: 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);
Trong trường hợp bạn cần phải chuyển đổi một struct timeval (giây, micro) có chứa UNIX time
tới DateTime
mà không làm mất độ chính xác, đây là cách làm:
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);
}
Kể từ .Net 4.6 trở lên, vui lòng sử dụng DateTime Offerset.Now.ToUnixTimeSeconds ()
Đây là giải pháp của tôi:
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);
}