2017-02-08 14 views
1

私が知っているように、我々はUNIXタイムスタンプは、VB日VBAでは、UTCのUNIXタイムスタンプをローカルタイムゾーンに変換する方法は簡単ですか?

CDate関数([UNIXタイムスタンプ]/60/60/23)+ "1970年1月1日"

に変換大まかに下に使用することができます

ただし、タイムゾーンと昼光情報は考慮されません。

タイムゾーンは大したことではありません。しかし、私は、特定のUNIXタイムスタンプの日光バイアス情報を取得することはできません。

Date 1/1の日光バイアスはDate 6/1とは明らかに異なりますが、Date 3/12またはDate 11/5の場合、日中のバイアス計算は非常に複雑です。

"FileTimeToLocalFileTime"や "GetTimeZoneInformation"のようないくつかのAPIを試しましたが、どちらも機能しませんでした。ここで

は、夏時間バイアス

Option Explicit 

#If VBA7 Then 
    Private Declare PtrSafe Function LocalFileTimeToFileTime Lib "kernel32" ([email protected], [email protected]) As Long 
    Private Declare PtrSafe Function FileTimeToLocalFileTime Lib "kernel32" ([email protected], [email protected]) As Long 
#Else 
    Private Declare Function LocalFileTimeToFileTime Lib "kernel32" ([email protected], [email protected]) As Long 
    Private Declare Function FileTimeToLocalFileTime Lib "kernel32" ([email protected], [email protected]) As Long 
#End If 

Public Function ToUTC(ByVal datetime As Date) As Date 
    Dim [email protected], [email protected] 
    ftLoc = (datetime - #1/1/1601#) * 86400000 
    LocalFileTimeToFileTime ftLoc, ftUtc 
    ToUTC = ftUtc/86400000# + #1/1/1601# 
End Function 

Public Function FromUTC(ByVal datetime As Date) As Date 
    Dim [email protected], [email protected] 
    ftUtc = (datetime - #1/1/1601#) * 86400000 
    FileTimeToLocalFileTime ftUtc, ftLoc 
    FromUTC = ftLoc/86400000# + #1/1/1601# 
End Function 

Function getDateFromTimestamp(ByVal value) As Date 
    Dim t1, t2 
    t1 = CDate(value/60/60/24) + "1/1/1970" 
    t2 = FromUTC(t1) 
    Debug.Print t2 - t1 
    getDateFromTimestamp = t2 
End Function 
+0

*からタイムスタンプ*を取得していますか?なぜすべてが「通貨」のタイプで宣言されていますか? – Comintern

+0

通貨はありませんでしたか? UNIXのタイムスタンプは、DBのhttp jsonテキストからのものです。 –

+1

'src @'は 'src As Currency'と同じものです。型ヒントについては、[documentation page](http://stackoverflow.com/documentation/vba/877/declaring-variables/2960/type-hints)を参照してください。 – Comintern

答えて

2

を扱うことができない私のコードは、おそらく最も簡単な方法は、.NETに組み込まれDateTime APIを使用してCOM相互運用機能経由です。このアプローチの良いイントロはin this answerです。

C#クラスライブラリを作成します。簡単にするには、.NET Framework 4.6以降をターゲットにして、クラスのFromUnixTimeSecondsToUnixTimeSecondsメソッドを使用できます。あなたが尋ねた何のため

using System; 
using System.Runtime.InteropServices; 

namespace MyDateTimeLibrary 
{ 
    [Serializable] 
    [ComVisible(true)] 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    public class DateTimeFunctions 
    { 
     public DateTime UnixTimeToDateTime(int unixTimeInSeconds) 
     { 
      return DateTimeOffset.FromUnixTimeSeconds(unixTimeInSeconds).UtcDateTime; 
     } 

     public long DateTimeUtcToUnixTime(DateTime utcDateTime) 
     { 
      return new DateTimeOffset(utcDateTime, TimeSpan.Zero).ToUnixTimeSeconds(); 
     } 

     public DateTime UtcToLocal(DateTime utcDateTime) 
     { 
      return utcDateTime.ToLocalTime(); 
     } 

     public DateTime LocalToUtc(DateTime localDateTime) 
     { 
      return localDateTime.ToUniversalTime(); 
     } 

     public DateTime TZSpecificDateTimeToUTC(DateTime sourceDateTime, string sourceTimeZoneId) 
     { 
      var tzi = TimeZoneInfo.FindSystemTimeZoneById(sourceTimeZoneId); 
      return TimeZoneInfo.ConvertTimeToUtc(sourceDateTime, tzi); 
     } 

     public DateTime UTCToTZSpecificDateTime(DateTime utcDateTime, string destinationTimeZoneId) 
     { 
      var tzi = TimeZoneInfo.FindSystemTimeZoneById(destinationTimeZoneId); 
      return TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, tzi); 
     } 
    } 
} 

、あなたは本当にのみ上記のコードからUnixTimeToDateTimeUtcToLocal方法を必要とするが、私は似たような状況にあってもよい他の人のためにいくつかのより多くを投げるだろうと思っていました。本当に、あなたがここで行うことができる.NETで何かできます。 .NET DateTimeDateTimeOffsetおよびTimeZoneInfo APIは、同様の作業を行う必要があるWin32 APIよりもはるかに簡単で信頼性が高くなります。

Register for COM interopオプションをビルドする前に(前のリンクに記載されているように)チェックしてください。そうでなければ、別のマシンにデプロイする場合はRegAsm.exeユーティリティを使用してDLLをCOMに登録してください。

次に、VBAプロジェクトの参照を新しく登録したMyDateTimeLibraryに追加します。そして、その(例えば)のように、それを使用する:

Sub Test() 

    Dim dtf As New MyDateTimeLibrary.DateTimeFunctions 
    Dim utcDt As Date, localDt As Date 

    utcDt = dtf.UnixTimeToDateTime(1487010504) 
    localDt = dtf.UtcToLocal(utcDt) 

    MsgBox ("UTC: " + CStr(utcDt) + vbCrLf + "Local: " + CStr(localDt)) 

    Set dtf = Nothing 

End Sub 

screenshot

私はからそれらを呼び出し、あなたは変換する日付内外に渡すいくつかの有用なVBA関数を記述するために、これをリファクタリングすることができます確信していますExcelセル、またはあなたのコンテキストが何であっても。私はあなたにその部分を残します。

+0

あなたの答えをありがとう!私の検証後、あなたは正しいです。 –

関連する問題