【问题标题】:Add to Google Calendar render link not showing user's local time添加到 Google 日历呈现链接不显示用户的本地时间
【发布时间】:2021-06-30 10:45:52
【问题描述】:

我可以使用这个指向谷歌日历的链接来创建一个活动。 但我认为时间即将到来(比我想要的活动时间提前 5.30 小时)

示例: This link 将创建一个事件,但它显示的时间是从中午 12.30 到下午 4 点。 这个活动应该是早上 6.30 到 10 点。

According to this link,从时间字符串中删除 Z 应该在事件中设置用户的本地时间。

使用用户的时区:20201231T193000/20201231T223000(不指定时区);

要使用 UTC 时区,请将 datetime 转换为 UTC,然后使用 Z 后缀:20201231T193000Z/20201231T223000Z;

我也尝试了this link 的相同解决方案,但活动时间仍未到来。它在链接中被转换。

const startDateTimeFormattedGoogle = eventStartDateTime ? eventStartDateTime.format(
        "YYYYMMDDTHHmmss"
      ) : null;
      const endDateTimeFormattedGoogle = eventEndDateTime ? eventEndDateTime.format(
        "YYYYMMDDTHHmmss"
      ) : null;
      const addToGoogleLink = `https://calendar.google.com/calendar/render?action=TEMPLATE&dates=${startDateTimeFormattedGoogle}/${endDateTimeFormattedGoogle}&location=${data.location}&text=${data.title}`;

更新:

console.log(88888, moment(eventStartDateTime).format('YYYYMMDDTHHmmssZ'),
result: 88888 20210430T123000+00:00 20210430T160000+00:00

console.log(111111, moment(eventStartDateTime).format('YYYYMMDDTHHmmss'),
        moment(eventEndDateTime).format('YYYYMMDDTHHmmss'))
result : 111111 20210430T123000 20210430T160000

result url: https://calendar.google.com/calendar/render?action=TEMPLATE&dates=20210430T123000+00:00/20210430T160000+00:00&location=Calgary, Downtown&text=The 2020 Festival

【问题讨论】:

  • 哦,我明白了,这是否意味着如果我提供 Z,它将转换为用户的时区?我说对了吗?
  • 不确定这是怎么回事。我添加了 Z 并将其删除。我用最新发现更新了这个问题。无论时区如何,我的节点 js 服务器上的时间都会打印相同的时间。客户端机器上的最终网址也始终显示相同的时间。

标签: javascript timezone momentjs google-calendar-api


【解决方案1】:

时区不是这样工作的。当您从字符串中删除 "Zulu time"(+00:00 偏移量,即 UTC)后缀时,您提供的时间将被区域设置系统使用。这会导致显示的时间与提供的时间相同:

Offset Raw Value Locale-unaware Locale-aware
+03:00 20210430T123000 2021-04-30 12:30:00 2021-04-30 12:30:00

如果您保留后缀,则表示您提供的时间是世界协调时间(或 UTC)格式。然后,时间会被 Google 日历等区域感知系统相应地调整(前提是用户没有禁用时区调整):

Offset Raw Value Locale-unaware Locale-aware
+03:00 20210430T123000Z 2021-04-30 12:30:00 2021-04-30 15:30:00

接下来,YYYYMMDDTHHmmSSZ 是一个有效的 Moment.js format string,所以如果你直接插入它,令牌语义就会发挥作用:

Token Repetitions Meaning Example
Y 4 Long (4-digit) year format 2021
M 2 Short month format, padded to 2 digits if necessary 01..12
D 2 Day of Month format, padded to 2 digits if necessary 01..31
T 1 literal T, no special formatting meaning, so no need to escape T
H 2 24-hour hour format, padded to 2 digits if necessary 00..23
m 2 Minutes format, padded to 2 digits if necessary 00..59
S 2 Fractional seconds format 00..99
Z 1 Time Zone, sign + 4 digits without colon +0000, -0000

您可以猜到,YYYYMMDDTHHmmssZ 格式字符串避免了“小数秒”警告,但使 Z 未转义,因此被视为时区指示符。根据文档,这可以通过适当的转义来解决:

要对格式字符串中的字符进行转义,可以将字符括在方括号中。

自己尝试一下(仅供参考,因为您使用的是 Moment.js,如果您不是严格强制使用它,请不要,它是 officially deprecated 支持其他库,直到 Temporal proposal 发货) :

(() => {
  const data = {
    location: "Calgary, Downtown",
    title: "The 2020 Festival"
  };

  const eventStartDateTime = new Date();
  const eventEndDateTime = new Date();

  const startDateTimeFormatted = moment(eventStartDateTime).format("YYYYMMDDTHHmmss[Z]");
  const endDateTimeFormatted = moment(eventEndDateTime).format("YYYYMMDDTHHmmss[Z]");

  const link = `https://calendar.google.com/calendar/render?action=TEMPLATE&dates=${startDateTimeFormatted}/${endDateTimeFormatted}&location=${data.location}&text=${data.title}`;

  const anchor = document.createElement("p");
  anchor.textContent = link;

  document.body.append(anchor);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

【讨论】:

  • @newdeveloper - NP,“将日期时间转换为 UTC”可能是造成混淆的原因,他们应该说这并不意味着 adjust (并使用“格式”有点错误,因为 Z 通常被理解为格式字符串,而不是文字后缀)
猜你喜欢
  • 2012-05-16
  • 2014-03-31
  • 1970-01-01
  • 2016-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多