猿问

HubSpot API 的日期时间转换不起作用

我正在通过他们的 API 将日期/时间值推送到 HubSpot CRM 系统中。对于日期/时间值,HS API 需要 UNIX 格式,它是从 Epoch (1/1/1970 12:00 AM) 开始的毫秒数。[HubSpot 文档:https://developers.hubspot.com/docs/faq/how-should-timestamps-be-formatted-for-hubspots-apis]


但是我的日期表示不正确。我正在从 EST 中的 SQL 数据库中提取日期,并执行以下转换:


string dbValue = "2019-02-03 00:00:00";

DateTime dt = Convert.ToDateTime(dbValue);

DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);

long apiValue = Convert.ToInt64(dt.Subtract(epoch).TotalMilliseconds);

但是,在 HubSpot 中,日期字段显示2/2/2019. HubSpot 中的时区设置为 UTC -4 东部时间。


似乎存在一些转换问题,但我不知道如何纠正它。我试过在转换为 long 之前使用DateTime.SpecifiyKind显式设置为本地:dt


dt = DateTime.SpecifyKind(dt, System.DateTimeKind.Local);

但这也没有用。我尝试做一个基本测试:


var dt1 = new DateTime(2019, 4, 1, 12, 0, 0, DateTimeKind.Local);

var dt2 = new DateTime(2019, 4, 1, 12, 0, 0, DateTimeKind.Utc);

Console.WriteLine(dt1.Subtract(dt2).TotalSeconds);

但结果是0。我在 CST,我预计会有 5 小时的差异。我觉得我在这里缺少一些关于 DateTimes 如何在 C# 中工作的基本概念。


慕娘9325324
浏览 127回答 1
1回答

宝慕林4294392

一些东西:DateTime不考虑减去值DateTimeKind。.NET Framework 4.6 及更高版本在类中内置了与 Unix 时间之间的转换函数DateTimeOffset,因此您根本不需要做任何减法。当你说ESTorCST时,我假设你指的是美国东部时间或美国中部时间。请记住,由于夏令时,这EDT或CDT可能适用于您的某些值。如果该值来自您的数据库,则不应从字符串中进行解析。我假设你只是在这里给出了这个例子。但是在您的实际代码中,您应该执行以下操作:DateTime dt = (DateTime) dataReader("field");(如果您正在使用 Entity Framework 或其他一些 ORM,那么这部分将为您处理。)SQL Server位于哪个时区并不重要。重要的是dbValue您打算代表哪个时区。最佳做法是使用 UTC 时间,在这种情况下,服务器的时区应该无关紧要。如果存储在 SQL Server 中的日期时间实际上是 UTC,那么您可以简单地执行以下操作:long apiValue = new DateTimeOffset(dt, TimeSpan.Zero).ToUnixTimeMilliseconds();如果存储在 SQL Server 中的日期时间确实是美国东部时间,那么您需要先将东部时间转换为 UTC:TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); DateTime utc = TimeZoneInfo.ConvertTimeToUtc(dt, tz); long apiValue = new DateTimeOffset(utc).ToUnixTimeMilliseconds();请注意,Windows 时区 ID"Eastern Standard Time"代表美国东部时间,包括适用时的美国东部时间,尽管中间有“标准”一词。如果您在非 Windows 平台上运行 .NET Core,请"America/New_York"改为传递。(如果您需要为跨平台弹性编写代码,请使用我的TimeZoneConverter库。)最后,虽然假设数据库中的时间与访问数据库的代码在同一本地时间可能有点危险,但如果您真的想进行这样的赌博,您可以这样做:long apiValue = new DateTimeOffset(dt).ToUnixTimeMilliseconds();这仅在dt.KindisDateTimeKind.Unspecified或时有效DateTimeKind.Local,因为它将应用本地时区。但我再次建议不要这样做。
随时随地看视频慕课网APP
我要回答