Еквівалент Java System.currentTimeMillis () у C #


Відповіді:


90

Альтернатива:

private static readonly DateTime Jan1st1970 = new DateTime
    (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

public static long CurrentTimeMillis()
{
    return (long) (DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
}

2
Той самий результат із "DateTimeOffset.UtcNow.ToUnixTimeMilliseconds ()"
— Рамунас,

74

Поширеною ідіомою в Java є використання currentTimeMillis()для цілей синхронізації або планування, коли вас не цікавлять фактичні мілісекунди з 1970 року, а замість цього обчислюють якесь відносне значення і порівнюють пізніші виклики з currentTimeMillis()цим значенням.

Якщо це те, що ви шукаєте, еквівалент C # є Environment.TickCount.


1
Але вони обидва дають різницеві числа. Як вони правильно порівнюють ?? C# give : 2688547таJava give : 1390707872687
— Ельшан

1
@Elshan Ви не можете їх порівняти. Вони різні кліщі. Цей прийом призначений для синхронізації та планування в межах програми, а не між програмами.
— Barend

System.currentTimeMillis()повертає час UTC у мс з 1970 р., тоді як Environment.TickCountповертає мс з моменту запуску програми. System.currentTimeMillis()добре для перевірки минулого часу, але якщо ви хочете, щоб дві тривалості були порівнянними, ви повинні використовувати System.nanoTime().
— michelpm

12

Якщо вас цікавить TIMING, додайте посилання на System.Diagnostics і використовуйте секундомір.

Наприклад:

var sw = Stopwatch.StartNew();
...
var elapsedStage1 = sw.ElapsedMilliseconds;
...
var elapsedStage2 = sw.ElapsedMilliseconds;
...
sw.Stop();


7

System.currentTimeMillis()в Java повертає поточний час в мілісекундах від 1/1/1970

c # це було б

public static double GetCurrentMilli()
    {
        DateTime Jan1970 = new DateTime(1970, 1, 1, 0, 0,0,DateTimeKind.Utc);
        TimeSpan javaSpan = DateTime.UtcNow - Jan1970;
        return javaSpan.TotalMilliseconds;
    }

редагувати: зробив це utc, як запропоновано :)


4
DateTime.Now використовує місцевий час, а не UTC. Я не знаю точно, що відбувається, коли віднімаєш невідомий тип DateTime з локального, але найкраще встановити їх обох на UTC :)
— Джон Скіт,

7

Ми також можемо трохи пофантазувати і зробити це як метод розширення, щоб він завис від класу DateTime:

public static class DateTimeExtensions
{
    private static DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    public static long currentTimeMillis(this DateTime d)
    {
        return (long) ((DateTime.UtcNow - Jan1st1970).TotalMilliseconds);
    }
}

3
Чи не трохи це неправильно? Цей метод розширення передаватиметься до будь-якого екземпляра DateTime, але він не використовує екземпляр. Просто здається заплутаним ... Я не думаю, що вам потрібно вимагати параметр, який ви не використовуєте
— mortb

1
@mortb Це метод розширення. Ось як це визначається в C # для "додавання методу" до класу без зміни класу. Компілятор інтерпретує метод і може застосувати його до екземпляра параметра "this" так, ніби це метод екземпляра в самому класі. Він функціонує так само, як метод у статичному класі, але компілятор дозволяє писати простіший, альтернативний синтаксис.
— Suncat2000

1
Проблема в тому, що значення параметра dне використовується. Для використання цього коду ви можете написати, var date = new DateTime(); var millis = date.currentTimeMillis();але dateзмінна буде просто надлишковою, і її стан ніколи не використовуватиметься. Коли не використовується стан об'єкта, створення методу розширення просто затемнює код. Відповідь, надана @Hath, є більш прямою і, отже, кращою (для мене). Можливо, @ Joel Coehoorn мав намір використовувати значення dзамість DateTime.UtcNowу тілі методу? Я використовую методи розширення досить багато, але не для цього.
— mortb

Чому б вам створити розширення, яке не використовує дату? Я використав цей код, і він мене зачепив. Правильна версія: return (long) ((d.ToUniversalTime () - Jan1st1970) .TotalMilliseconds);
— Марк Г

4

Ось простий спосіб наблизити позначку часу Unix. Використання UTC наближається до концепції unix, і вам потрібно приховувати від doubleдо long.

TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
long millis = (long)ts.TotalMilliseconds;
Console.WriteLine("millis={0}", millis);

відбитки:

millis=1226674125796

саме те, що мені потрібно.
— Аджибола,

3

Структура не включає старі секунди (або мілісекунди) з 1970 року. Найбільш близьким є DateTime.Ticks, що є числом 100-наносекунд з 1 січня 0001 року.


1
Чи дав би (DateTime.Ticks / 10000000) - (кількість секунд між 0001 і 1970) точну відповідь?
— Ліам,

3

Я просто розглядаю найбільш прямий шлях, як досягти того, до чого ви прагнули, наступним чином:

DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond

1
DateTime.UtcNowє кращим варіантом
— Мехді Хадемлу

2

Якщо ви хочете, щоб мітка часу порівнювалася між різними процесами, різними мовами (Java, C, C #), під GNU / Linux та Windows (принаймні сім):

C #:

private static long nanoTime() {
   long nano = 10000L * Stopwatch.GetTimestamp();
   nano /= TimeSpan.TicksPerMillisecond;
   nano *= 100L;
   return nano;
}

Java:

java.lang.System.nanoTime();

C GNU / Linux:

static int64_t hpms_nano() {
   struct timespec t;
   clock_gettime( CLOCK_MONOTONIC, &t );
   int64_t nano = t.tv_sec;
   nano *= 1000;
   nano *= 1000;
   nano *= 1000;
   nano += t.tv_nsec;
   return nano;
}

C Windows:

static int64_t hpms_nano() {
   static LARGE_INTEGER ticksPerSecond;
   if( ticksPerSecond.QuadPart == 0 ) {
      QueryPerformanceFrequency( &ticksPerSecond );
   }
   LARGE_INTEGER ticks;
   QueryPerformanceCounter( &ticks );
   uint64_t nano = ( 1000*1000*10UL * ticks.QuadPart ) / ticksPerSecond.QuadPart;
   nano *= 100UL;
   return nano;
}

1

Я знаю, запитання вимагає еквівалента, але оскільки я використовую ці 2 для тих самих завдань, я кидаю в GetTickCount . Я можу бути ностальгічним, але System.currentTimeMillis () та GetTickCount () - це єдине, що я використовую для отримання кліщів.

[DllImport("kernel32.dll")]
static extern uint GetTickCount();

// call
uint ticks = GetTickCount();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.