Відповіді:
Ви отримуєте часову позначку 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)
DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
Що стосується .NET 4.6, існує DateTimeOffset.ToUnixTimeSeconds()
.
Це метод екземпляра, тому очікується, що ви будете викликати його за екземпляром DateTimeOffset
. Ви також можете передавати будь-який примірник DateTime
, хоча остерігайтеся часового поясу .
Щоб отримати поточну позначку часу:
DateTimeOffset.UtcNow.ToUnixTimeSeconds()
Щоб отримати позначку часу від DateTime
:
DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Int64
- до того моменту, коли він перевернеться, ми вже не будемо використовувати Землі років для нестачі Землі.
DateTimeOffset.Now.ToUnixTimeSeconds()
Ви також можете використовувати кліщів. Я кодую 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;
new DateTime(1970, 1, 1)
створює час із невизначеним Kind
властивістю. Що ви хочете new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
бути справді правильним
Це те, що я використовую:
public long UnixTimeNow()
{
var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
return (long)timeSpan.TotalSeconds;
}
Майте на увазі, що цей метод поверне час як координований універсальний час (UTC).
double
Тип " TotalSeconds" ; перенесення його на довгий час призведе до втрати точності.)
Обрізка .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);
}
Коли ви віднімаєте 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.
Це те, що я використовую.
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;
}
}
Я об'єднав найелегантніші підходи до цього корисного методу:
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;
}
Це рішення допомогло в моїй ситуації:
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)
Для системи DataTimeOffset у системі є ToUnixTimeMilliseconds
Ви можете написати подібний метод для DateTime:
public static long ToUnixTimeSeconds(this DateTime value)
{
return value.Ticks / 10000000L - 62135596800L;
}
10000000L - перетворення кліщів в секунди
62135596800L - перетворення 01.01.01 на 01.01.1978
Немає проблем з Utc та протіканнями
Нижче наведено двосторонній клас розширення, який підтримує:
У випадку з ОП використання:
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;
}
}
}
Я використовував це, боровшись деякий час, це також відповідає зміщенню часового поясу:
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;
}
Простий код, який я використовую:
public static long CurrentTimestamp()
{
return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds * 1000);
}
Цей код дає часову позначку Unix, загальна мілісекунда з 1970-01-01 по теперішній час.