在VBA中,如何以简单的方式将UTC UNIX时间戳转换为本地时区日期?

2024-01-09

据我所知,我们可以使用下面的方法将 UNIX 时间戳粗略地转换为 VB 日期

CDate([UNIX 时间戳]/ 60 / 60 / 24) + "1/1/1970"

但是,不考虑时区和日光信息。

时区并不是什么大问题。但我无法获取特定 UNIX 时间戳的夏令时偏差信息。

虽然日期 1/1 的日光偏差与日期 6/1 明显不同,但是对于日期 3/12 或日期 11/5,日光偏差计算非常复杂。

我尝试了几个 API,例如“FileTimeToLocalFileTime”和“GetTimeZoneInformation”,但它们都不起作用。

这是我的代码,无法处理日光偏差

Option Explicit

#If VBA7 Then
  Private Declare PtrSafe Function LocalFileTimeToFileTime Lib "kernel32" (src@, tgt@) As Long
  Private Declare PtrSafe Function FileTimeToLocalFileTime Lib "kernel32" (src@, tgt@) As Long
#Else
  Private Declare Function LocalFileTimeToFileTime Lib "kernel32" (src@, tgt@) As Long
  Private Declare Function FileTimeToLocalFileTime Lib "kernel32" (src@, tgt@) As Long
#End If

Public Function ToUTC(ByVal datetime As Date) As Date
  Dim ftLoc@, ftUtc@
  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 ftUtc@, ftLoc@
  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

可能最简单的方法是通过 COM Interop 来使用DateTime.NET 内置的 API。对于这种方法有一个很好的介绍在这个答案中 https://stackoverflow.com/a/19955042/634824.

创建 C# 类库。为了让事情变得更简单,请以 .NET Framework 4.6 或更高版本为目标,这样您就可以使用FromUnixTimeSeconds and ToUnixTimeSeconds上的方法DateTimeOffset class.

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);
        }
    }
}

对于你所要求的,你真的只需要UnixTimeToDateTime and UtcToLocal上面代码中的方法,但我想我应该为其他可能处于类似情况的人提供更多的方法。实际上,您可以在 .NET 中执行的任何操作都可以在这里执行。互联网DateTime, DateTimeOffset and TimeZoneInfoAPI 比完成类似工作所需的 Win32 API 更简单、更可靠。

检查Register for COM interop构建之前的选项(如前面链接的答案中所述),或者通过 COM 注册您的 DLLRegAsm.exe如果您要部署到另一台计算机,则可以使用该实用程序。

接下来,将 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

我相信您可以重构它来编写一些有用的 VBA 函数,这些函数可以传入和传出要转换的日期、从 Excel 单元格或任何您的上下文中调用这些函数。我会把这部分留给你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在VBA中,如何以简单的方式将UTC UNIX时间戳转换为本地时区日期? 的相关文章

  • Excel:如何通过VBA搜索电子表格1值是否存在于电子表格2中

    在电子表格 1 中 B 列包含值 即 V 9999 我正在尝试查看电子表格 2 的 B 列中是否存在这些值 我遇到的问题是 每次更新电子表格时数据都会发生变化 并且 B 列中的每行之间并不总是 1 1 匹配 例如 V 9999 可能存在于电
  • 如果我后面不写“as Something”,用“Dim”来声明变量是没有用的吗?

    例如 下面两个代码是否相同 如果我之后不写 作为整数 是否没有必要使用 Dim Sub something MyNumber 10 Worksheets 1 Range A1 MyNumber End Sub and Sub somethi
  • 如何从偏移量获取时区名称?

    我正在使用时刻时区进行时区计算 我都有一些offset来自数据库的数据 例如GMT GMT 1 GMT 2 GMT 3 GMT 4 etc 无论如何 我可以从这些数据中获取时区或时区名称 例如 America Los Angeles 吗 我
  • 如何使用 VBA 在 PowerPoint 中取消形状组合后按类型重新组合形状

    继我的出色回答之后上一个问题 https stackoverflow com questions 74339247 how to rename shapes within grouped groups in powerpoint with
  • 如何在 VBA 中克隆范围对象

    我正在使用 Excel Visual Basic 编辑器在 VBA 中编写 Excel 宏 我不知道如何复制 克隆范围对象 而不是创建对同一对象的第二个引用 MemberwiseClone 函数似乎不可用 我认为它将针对内置类型实现 我需要
  • VBA - 从 Internet Explorer 的框架通知栏中选择另存为

    我正在尝试通过以下方式下载另存为的文件框架通知栏的互联网浏览器 然而 经过大量搜索后 我只找到了点击解决方案save在框架通知栏上 到目前为止 我一直在尝试另存为示例站点上的文件 http www tvsubtitles net subti
  • 检索形状的名称

    在 Excel 中 左上角有 名称框 但我找不到在 Word 中检索形状名称的方法 我怎么做 MS Word 中有两种形状 InlineShapes and Shapes 使用一些 VBA 代码检查形状对象的名称非常容易 选择形状 按 Al
  • 将 vbCrLf 应用于文本框的内容

    我在 Excel vba 项目中有一个用户窗体 在设计时它是空的 在表单初始化事件中 我有以下代码 Private Sub UserForm Initialize txtSQL value SELECT MyName ColY vbCrLf
  • VBA - 循环遍历表单上的控件并读取值

    我想循环遍历表单上的控件并读取值 但是 Value 和 Checked 属性不可用 我的问题是 当我循环访问控件 在本例中为复选框 时 如何读取它们的值 Dim Ctrl as Control For Each Ctrl In frmMai
  • 如何在 Excel 的 VBA 中求负数的立方根?

    我正在尝试在 Excel 的 VBA 中计算负数的立方根 在 Excel 工作表中取负数的立方根效果很好 2 1 3 1 25992 然而 相同的概念被编码到 VBA 中 2 1 3 gives a VALUE 将值返回到工作表时出错 我怀
  • VBA:新集合 -> 模块不是有效类型

    我尝试使用集合作为函数的一部分 但是在编译时不断收到错误 模块不是有效类型 即使该函数只是定义一个集合 我也会得到相同的结果 Function CountUniqueTags Dim table As Collection Set tabl
  • 将数据从 Excel 导出到 Outlook

    我已经用 Excel 起草了一封电子邮件 其中填充了数据表中的信息 单元格 A1 到 A4 包含 嗨 希望你做得好 和消息 等等 A5到H10有一个包含信息的表格 A11到A30有类似 期待您的回复 的电子邮件内容 我只想复制 A1 A4
  • 使用 VBA 清除 Excel 单元格格式而不清除 NumberFormat

    是否可以在不改变 的情况下清除Excel单元格格式和内容 使用VBA NumberFormat 给定的单元格 我尝试过 ClearContents ClearFormats 但 ClearFormats 删除了数字格式细胞也 请建议 你可以
  • 通过vba在每个空间范围之间添加求和公式

    我试图进行自动化 但我被困在这里 我需要在空间范围之间动态添加总和公式 我完全迷失了使用 VBA 添加公式的能力 任何人都可以帮助我 先感谢您 我假设您想要的是 如果单元格中有空白 您希望将所有其他元素相加并将结果放置在该空白中 可能有很多
  • 有皮茨时区列表吗?

    我想知道 Python 库 pytz 中时区参数的所有可能值是什么 怎么做 您可以列出所有可用的时区pytz all timezones In 40 import pytz In 41 pytz all timezones Out 42 A
  • 全日历和时区。求助,我做错了

    我不知何故做错了 我被时区绊倒了Fullcalendar 我尝试过设置ignoreTimezone真与假 不过似乎并不重要 它在下面的代码中的两个地方 因为我不确定它在哪里 我的数据源是隐藏的表单字段 数据流转out of FullCale
  • 使用 VBA 在另一个 Access 实例中打开特定窗体

    所以我在这里四处查看并找不到我的问题的答案 至少不完全是 案例如下 我在 DBase1 中 想要单击一个按钮并在单独的访问实例中打开 DBase2 中的 NeuSteckbrief 表单 我设法使用以下代码在单独的实例中打开 DBase2
  • 规则和夏令时

    我在用着rrule https github com jakubroztocil rrule在我的数据库中创建和存储事件 一切正常 直到我发现我的重复事件与 3 月 31 日之后有一个小时的差异 在法国 这一天我们进行夏令时更改 实际上 我
  • VBA:删除数组项后减少循环迭代?

    在 Excel 的 VBA 中 For i 0 To UBound artMaster For j i To UBound artMaster If i lt gt j And artMaster i VDN artMaster j VDN
  • Python:使用 python 运行 Excel 宏

    我需要通过 python 运行 Excel 宏 但总是收到以下错误 result self oleobj InvokeTypes dispid LCID wFlags retType argTypes args pywintypes com

随机推荐

  • 获取城市名称不以元音开头或不以元音结尾

    从 STATION 查询不以元音开头或不以元音结尾的 CITY 名称列表 您的结果不能包含重复项 输入格式 STATION表描述如下 我写了下面的查询 但它对我不起作用 有什么建议吗 select distinct city from st
  • GitHub - 查找与提交关联的拉取请求

    我正在尝试查找过去的拉取请求 以查看对特定问题做出了哪些评论 操作 我知道该文件和更改 因此我可以通过查看指责视图来访问引入该文件的提交 但是 我找不到一种方法来查看第一次将该提交推送到分支的拉取请求 有没有办法做到这一点 或者我是否必须沿
  • ./*/ 是可移植的吗?

    我经常使用 在 for 循环中 for d in do do something with dirs done 匹配当前工作目录中的所有非隐藏目录 但我不确定这是否是一种可移植的方法 我的系统上安装了 bash dash 和 ksh 并且它
  • MySQL 返回其中列包含集合中的任何但仅包含关键字的所有行

    有没有一种方法可以选择其中一列仅包含但任意数量的预定义值的行 我一直在使用这个 但它返回我的列至少包含一个值的任何行 我知道这正是它应该做的 但我正在寻找一种方法来仅选择关键字列中仅包含我的关键字的行 SELECT FROM product
  • 如何以角度拖动和重新排序内容

    我有5个不同的内容 我想将其拖动并重新排序在同一行中 我如何在角度 2 4 5 或 6 中执行此操作 如果有人知道 请帮助我执行此操作 堆栈闪电战 https stackblitz com edit angular cc9ztn file
  • 如何在C++中随机分配给向量?

    我是 C 新手 并且不断被告知要使用std vector代替new 我正在尝试实现此功能 其中我知道向量的大小并希望随机 而不是顺序 分配给它 然而 当运行这个时 我的程序终止且没有错误输出 所以我很困惑 vector
  • OpenCV DNN,从tensorflow导入.pb文件断言失败错误:函数“populateNet”中的scaleMat.type() == CV_32FC1

    我试图导入一个冻结的 并使用tensorflow python tools optimize for inference优化 pb optimized pb 文件使用 cv2 dnn readNetFromTensorflow optimi
  • 匿名聚合中不允许使用构造函数,结构中的字符串

    所以我在尝试创建和使用这个结构时遇到了错误 使用字符而不是字符串的结构有效 但我发现我需要能够存储许多字母 使用下面的这个小代码示例后 我收到此错误 错误 成员 std cxx11 string GraphNode c1 在匿名聚合字符串
  • BlackBerry - Unicode 文本显示

    我想在 BlackBerry 设备上的 j2me 应用程序中的 LabelField 中显示一些阿拉伯文本 假设设备上安装了阿拉伯字体 在本地化资源中 如果使用阿拉伯语言环境 则所有文本都以 Unicode 序列保存 但是 如果我明确使用这
  • 在 R 中将不同的预测方法传递给分层时间序列预测?

    我有一个分层时间序列 其底层序列都表现出间歇性需求 使用 Hyndman 的 HTS 包在层次结构内实现最佳组合似乎是有利的 使用 Kourentzes 的 MAPA 包进行间歇性需求的多重聚合预测似乎也是有利的 本质上 我想做类似的事情
  • 编写 html 文件,其中包含在特定工作表和行中打开 Excel 应用程序的链接

    我正在编写一个非常简单的 HTML 文件 其中包含一些表格 我试图获得一个单元格值 它基本上是一个链接 通过单击链接 我想在 Excel 应用程序中的特定工作表和行中打开文件 Notes 视窗环境 HTML由标准浏览器打开 该文件存在于本地
  • 如何通过c# mvc函数传递两个参数来调用存储过程

    当我需要传递单个参数时 我可以轻松完成 如下所示 public ProjectsModel GetProjectListBySearch int projectId try using context new Exo ADBEntities
  • 有没有办法从某些 HTML 元素中排除 MathJax 处理?

    有没有办法从某些 HTML 元素中排除 MathJax 处理 例如 如果我知道 a 中没有任何数学 div 有没有办法标记它以便 MathJax 处理器跳过它 div 就在这里 使用tex2jax ignoreCSS 类 div class
  • C# 构造函数有 2 个参数,但声称它没有带有两个参数的构造函数

    所以这是我的问题 我有一个名为 Login 的类 它将用于登录和创建新的登录帐户 我创建了一个不带参数的登录构造函数 public Login gloID 0 Username null Password null Note null Ac
  • 逐个字段比较两个对象并显示差异[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想逐个字段比较两个对象 即两个数据库行 例如Object1 name ABC age 29 emai
  • 关于交易和 msdtc 的混淆

    我对事务和 msdtc 如何协同工作有一些基本的困惑 我有一个基本的服务器 客户端 winforms 应用程序 该应用程序使用transactionscope来封装在sql服务器上执行的多个sql命令 当我仅在服务器上启用 msdtc 网络
  • 作为“访问网络应用程序的用户”从 Google Apps 脚本提供 JSON

    尝试以发出请求的用户身份提供由 Google Apps 脚本发出的 JSON 请求 想了一会儿 我意识到这是行不通的 因为服务脚本需要被授权才能以调用他的用户身份运行 所以调用脚本必须添加一些授权信息 但它没有 我不知道如何添加该信息 这实
  • Electron 窗口无法打开,但不显示任何错误

    Context I 看到 这个问题 https stackoverflow com questions 52757597 electron app runs without any errors however the window doe
  • 类似的图片搜索软件(如TinEye)

    在我们的社区网站之一中 我们允许用户上传图像 这些图像由我们的版主批准或拒绝 为了限制管理员所需的工作 我们希望将每张被拒绝的图片 记录 到某种数据库中 并在提交图像以供批准之前在此数据库中进行查找 如果类似的图片已被拒绝 则上传的图片将不
  • 在VBA中,如何以简单的方式将UTC UNIX时间戳转换为本地时区日期?

    据我所知 我们可以使用下面的方法将 UNIX 时间戳粗略地转换为 VB 日期 CDate UNIX 时间戳 60 60 24 1 1 1970 但是 不考虑时区和日光信息 时区并不是什么大问题 但我无法获取特定 UNIX 时间戳的夏令时偏差