2015-04-21 9 views
9

В Java, чтобы получить системное время в миллисекундах я использую:Получить Unix время миллисекунды

new date().gettime() 

можно получить тот же результат в миллисекундах с помощью Excel VBA?

+0

Зачем вам системное время в миллисекундах? –

+0

Потому что через одну секунду я могу опубликовать> 1 раз, и мне нужно время управления каждым сообщением –

ответ

4

Аннотация: Для достижения наилучших результатов используйте GetSystemTime.

Функция рабочего листа Excel Now() имеет относительно хорошую точность, примерно до 10 мс. Но, чтобы назвать это, вы должны использовать формулу рабочего листа.

Чтобы правильно получить значение в миллисекундах, вы должны избежать Функция VBA Now(). Его точность составляет примерно 1 секунду.

Функция VBA Timer() возвращает single с точностью примерно 5 миллисекунд. Но вы должны использовать Now(), чтобы получить часть даты. Это может вызвать небольшую проблему, если Now() называется до в полночь и Timer() называется после полночь (это, вероятно, редкая ситуация, и это не проблема для большинства людей).

Функция Windows API GetSystemTime имеет истинную миллисекундную точность. Вы можете использовать значения в структуре SYSTEMTIME для создания двойника Excel, который имеет правильную миллисекундную точность. GetSystemTime возвращает время UTC, поэтому, если вам нужна дата в формате POSIX, вы можете вычесть эпоху UNIX (1 января 1970 UTC), которая равна 25569 в формате даты Excel (без учета секунд прыжка).

Код ниже сравнивает точность каждого метода:

Option Explicit 

Private Type SYSTEMTIME 
    wYear As Integer 
    wMonth As Integer 
    wDayOfWeek As Integer 
    wDay As Integer 
    wHour As Integer 
    wMinute As Integer 
    wSecond As Integer 
    wMilliseconds As Integer 
End Type 

Private Declare Sub GetSystemTime Lib "kernel32" (lpSystemTime As SYSTEMTIME) 

Function Now_System() As Double 
    Dim st As SYSTEMTIME 
    GetSystemTime st 
    Now_System = DateSerial(st.wYear, st.wMonth, st.wDay) + _ 
     TimeSerial(st.wHour, st.wMinute, st.wSecond) + _ 
     st.wMilliseconds/86400000# 
End Function 

Function Now_Timer() As Double 
    Now_Timer = CDbl(Int(Now)) + CDbl(Timer()/86400#) 
End Function 


Sub CompareCurrentTimeFunctions() 
    ' Compare precision of different methods to get current time. 
    Me.Range("A1:D1000").NumberFormat = "yyyy/mm/dd h:mm:ss.000" 

    Dim d As Double 
    Dim i As Long 
    For i = 2 To 1000 
     ' 1) Excel NOW() formula returns same value until delay of ~10 milliseconds. (local time) 
     Me.Cells(1, 1).Formula = "=Now()" 
     d = Me.Cells(1, 1) 
     Me.Cells(i, 1) = d 

     ' 2) VBA Now() returns same value until delay of ~1 second. (local time) 
     d = Now 
     Me.Cells(i, 2) = d 

     ' 3) VBA Timer returns same value until delay of ~5 milliseconds. (local time) 
     Me.Cells(i, 3) = Now_Timer 

     ' 4) System time is precise down to 1 millisecond. (UTC) 
     Me.Cells(i, 4) = Now_System 
    Next i 
End Sub 
3

Разная интерпретация, основанная на Excel posix time и с часовой поправкой на летнее время:

Sub Pose() 
    ut = ((Now - 25569) * 86400000) - 3600000 
End Sub 

Если не достаточно точным, http://vbadud.blogspot.co.uk/2008/10/excel-vba-timestamp-milliseconds-using.html может представлять интерес.

+0

Нет результата не так! Поскольку ваш пример возвращает всегда 000 в конце, а ваша ссылка возвращает не цифровую строку, так как мне нужно –

+0

Нет, Тип несоответствия –

+0

Повторите попытку !: '+ (Формат (Таймер,« 0.000 ») - Int (Формат (Таймер,« 0.000 "))) * 1000'. – pnuts

1

Это создает временную метку в формате yyyy mm dd hh:mm:ss.fff, где fff - миллисекунды.

Dim dateToday As Date 
Dim datetimeNow As Date 
Dim secondsElapsedSinceMidnight As Double 
Dim h As Long 
Dim m As Long 
Dim s As Long 

dateToday = Now 
secondsElapsedSinceMidnight = Timer 

h = Int(secondsElapsedSinceMidnight/3600) 
m = Int(secondsElapsedSinceMidnight/60) - h * 60 
s = Int(secondsElapsedSinceMidnight) - m * 60 - h * 3600 

datetimeNow = DateSerial(Year(dateToday), Month(dateToday), Day(dateToday)) _ 
    + TimeSerial(h, m, s) 

Debug.Print Format(datetimeNow, "yyyy mm dd hh:nn:ss.") _ 
    & Format((secondsElapsedSinceMidnight _ 
     - Int(secondsElapsedSinceMidnight)) * 1000, "000") 

Как я представляю этот ответ, выход:

2015 04 21 16:24:22.852 
+0

Это человекообразный формат, но мне нужны только цифры –

+1

Тогда просто не форматируйте его, как я сделал в конце! –

1

я нашел только один возможный вариант

Private Type SYSTEMTIME 
     wYear As Integer 
     wMonth As Integer 
     wDayOfWeek As Integer 
     wDay As Integer 
     wHour As Integer 
     wMinute As Integer 
     wSecond As Integer 
     wMilliseconds As Integer 
End Type 

Private Declare Sub GetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME) 
Sub test() 
Dim sSysTime As SYSTEMTIME 

GetLocalTime sSysTime 

MsgBox = ((Now - 25569) * 86400000) - 3600000 + sSysTime.wMilliseconds 
End Sub 
+0

Вам нужно избегать использования двух разных функций для получения времени. У вас будут несоответствия между этими двумя результатами. Чтобы получить лучшие результаты, используйте только структуру SYSTEMTIME. – bouvierr

2

Вот короткое расширение на ответ по @bouvierr, как я нуждался эквивалент метода java.lang.System.currentTimeMillis() в VBA:

Private Type SYSTEMTIME 
    wYear As Integer 
    wMonth As Integer 
    wDayOfWeek As Integer 
    wDay As Integer 
    wHour As Integer 
    wMinute As Integer 
    wSecond As Integer 
    wMilliseconds As Integer 
End Type 

Private Declare Sub GetSystemTime Lib "kernel32" (lpSystemTime As SYSTEMTIME) 

Function CurrentTimeMillis() As Double 
    ' Returns the milliseconds from 1970/01/01 00:00:00.0 to system UTC 
    Dim st As SYSTEMTIME 
    GetSystemTime st 
    Dim t_Start, t_Now 
    t_Start = DateSerial(1970, 1, 1) ' Starting time for Linux 
    t_Now = DateSerial(st.wYear, st.wMonth, st.wDay) + _ 
     TimeSerial(st.wHour, st.wMinute, st.wSecond) 
    CurrentTimeMillis = DateDiff("s", t_Start, t_Now) * 1000 + st.wMilliseconds 
End Function