Эквивалент Java System.currentTimeMillis () в C #

85

Что эквивалентно Java System.currentTimeMillis()в C #?

Мэтт Би
источник
Просто любопытно, зачем тебе миллис с 1970 года?
Alex B
5
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds ()
Рамунас

Ответы:

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();
bstabile
источник
8
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
Рамунас
источник
Этот DateTimeOffsetметод был введен в .Net 4.6.
Suncat2000
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;
    }

изменить: сделал это как было предложено :)

Hath
источник
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);
Mark G
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
TechCrap
источник
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.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();
Горько-синий
источник