Tôi đã xem xét xung quanh stackoverflow, và thậm chí đã xem xét một số câu hỏi được đề xuất và dường như không có câu trả lời nào, làm thế nào để bạn có được dấu thời gian unix trong C #?
Tôi đã xem xét xung quanh stackoverflow, và thậm chí đã xem xét một số câu hỏi được đề xuất và dường như không có câu trả lời nào, làm thế nào để bạn có được dấu thời gian unix trong C #?
Câu trả lời:
Bạn nhận được dấu thời gian unix trong C # bằng cách sử dụng DateTime.UtcNow
và trừ thời gian kỷ nguyên 1970-01-01.
ví dụ
Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
DateTime.UtcNow
có thể được thay thế bằng bất kỳ DateTime
đối tượng nào bạn muốn lấy dấu thời gian unix cho.
Ngoài ra còn có một lĩnh vực, DateTime.UnixEpoch
được MSFT ghi lại rất kém , nhưng có thể thay thế chonew DateTime(1970, 1, 1)
DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
Kể từ .NET 4.6, có DateTimeOffset.ToUnixTimeSeconds()
.
Đây là một phương thức cá thể, vì vậy bạn sẽ gọi nó theo một thể hiện của DateTimeOffset
. Bạn cũng có thể truyền bất kỳ trường hợp nào DateTime
, mặc dù hãy coi chừng múi giờ .
Để có được dấu thời gian hiện tại:
DateTimeOffset.UtcNow.ToUnixTimeSeconds()
Để lấy dấu thời gian từ một DateTime
:
DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Int64
- vào thời điểm đó, chúng ta sẽ không sử dụng Trái đất nhiều năm nữa vì thiếu Trái đất.
DateTimeOffset.Now.ToUnixTimeSeconds()
Bạn cũng có thể sử dụng Ticks. Tôi đang mã hóa cho Windows Mobile vì vậy không có bộ phương pháp đầy đủ. TotalSeconds không có sẵn cho tôi.
long epochTicks = new DateTime(1970, 1, 1).Ticks;
long unixTime = ((DateTime.UtcNow.Ticks - epochTicks) / TimeSpan.TicksPerSecond);
hoặc là
TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
TimeSpan unixTicks = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
double unixTime = unixTicks.TotalSeconds;
new DateTime(1970, 1, 1)
tạo ra một thời gian với Kind
tài sản không xác định . Những gì bạn thực sự muốn new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
là thực sự chính xác
Đây là những gì tôi sử dụng:
public long UnixTimeNow()
{
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
return (long)timeSpan.TotalSeconds;
}
Hãy nhớ rằng phương pháp này sẽ trả về thời gian là Thời gian chuyển tiếp phối hợp (UTC).
double
loại; kéo dài nó sẽ gây mất độ chính xác.)
Cắt ngắn .TotalSeconds
là quan trọng vì nó được định nghĩa làthe value of the current System.TimeSpan structure expressed in whole fractional seconds.
Và làm thế nào về một phần mở rộng cho DateTime
? Cái thứ hai có lẽ khó hiểu hơn là nó có giá trị cho đến khi phần mở rộng thuộc tính tồn tại.
/// <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);
}
Khi bạn trừ 1970 từ thời điểm hiện tại, hãy lưu ý rằng thời gian thường sẽ có trường không bằng mili giây. Nếu vì lý do nào đó bạn quan tâm đến mili giây, hãy ghi nhớ điều này.
Đây là những gì tôi đã làm để giải quyết vấn đề này.
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.
Đây là những gì tôi sử dụng.
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;
}
}
Tôi đã kết hợp các cách tiếp cận thanh lịch nhất với phương pháp tiện ích này:
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;
}
Giải pháp này đã giúp trong tình huống của tôi:
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;
}
}
sử dụng trình trợ giúp trong mã:
double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)
Có một ToUnixTimeMilliseconds cho DateTimePackset trong Hệ thống
Bạn có thể viết phương thức tương tự cho DateTime:
public static long ToUnixTimeSeconds(this DateTime value)
{
return value.Ticks / 10000000L - 62135596800L;
}
10000000L - chuyển đổi tick thành giây
62135596800L - chuyển đổi 01.01.01 thành 01.01.1978
Không có vấn đề với Utc và rò rỉ
Dưới đây là lớp mở rộng 2 chiều hỗ trợ:
Trong trường hợp của OP, cách sử dụng là:
DateTime.Now.ToUnixtime();
hoặc là
DateTime.UtcNow.ToUnixtime();
Mặc dù một câu trả lời trực tiếp tồn tại, tôi tin rằng sử dụng một cách tiếp cận chung là tốt hơn. Đặc biệt bởi vì rất có thể đó là một dự án cần chuyển đổi như thế này, dù sao cũng sẽ cần các tiện ích mở rộng này, vì vậy tốt hơn hết là sử dụng cùng một công cụ cho tất cả.
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;
}
}
}
Tôi đã sử dụng điều này sau khi vật lộn một lúc, nó cũng phục vụ cho phần bù múi giờ:
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;
}