【问题标题】:How to convert a UTC datetime string into users' current timezone?如何将 UTC 日期时间字符串转换为用户的当前时区?
【发布时间】:2019-09-07 06:53:38
【问题描述】:

我使用 laravel 5.7 作为 api 和 vue 作为前端。在 api 响应中,我将用户最后一次看到的时间戳记为 last_seen: "2019-04-17 05:20:37",默认情况下为 UTC 格式。

Laravel API 代码:

$user_details = array(
            'user_id' => $userId,
            'name' => $userDetails->name,
            'email' => $userDetails->email,
            'phone' => $userDetails->contact,
            'account_creation_date' => $userDetails->created_at->toDateTimeString(),
            'last_seen' => $lastSeen != null ? $lastSeen->toDateTimeString() : $userDetails->last_login->toDateTimeString(),
            'language' => 'English',
            'country' => $country->name
        );

$user_profile['user_details'] = $user_details;
return response()->api(true, 'Success', $user_profile);

这是我得到的 api 响应:

在前端,即在 vue 中,我使用 Dayjs Package 显示用户的最后一次显示为 [Day|Hours|Minutes] ago,但问题是 目标用户刚刚登录,但我知道它正在显示6 Hours ago

由于我在 Asia/Kolkata 时区,因此代码也需要 5.5/6 小时。

我也尝试使用moment.js,但我得到undefined function moment.tz.guess() 错误

这是我迄今为止尝试过的:

我将日期时间字符串传递给我的 vuejs 函数:

import dayjs from "dayjs";

convertFromNow(date) {
 return dayjs(date).fromNow();
},

然后调用这个方法打印为1 minute ago

<div class="side-box mt-4">
                  <h2 class="side-head">
                    <i class="fa fa-clock-o" />
                    {{ convertFromNow(userInfo.user_details.last_seen) }}
                    <h6 class="text-gray">
                      Last seen
                    </h6>
                  </h2>
                </div>

我需要的预期结果是,无论 UTC 时间是多少,我都应该根据我的时区获得用户的最后一次访问。

【问题讨论】:

  • 使用moment.js有什么问题?这是一个很棒的图书馆。
  • @iwaduarte 使用moment.js 没有问题,但我在猜测用户的时区时出错。
  • 另请参阅此链接以了解您的代码发生了什么。 github.com/moment/moment-timezone/issues/523 。您能否也编辑您的问题以包含您在 moment.js 中使用的代码?
  • 为什么您的 API 返回的日期/时间字符串没有时区信息?恕我直言,日期的最佳传输格式是 ISO 8601,即2019-04-17T05:20:37Z。这使它明确并且JS可以正确解析它。在我的浏览器中,解析您的 "2019-04-17 05:20:37" 字符串会将其视为当地时间(这似乎是您的问题)
  • 您可以使用toLocaleString()获取用户当前时间

标签: javascript laravel vue.js npm


【解决方案1】:

你也尝试使用moment.js,你需要告诉moment时间是UTC

console.log(moment.utc("2019-04-17 05:20:37").fromNow())
&lt;script src="https://momentjs.com/downloads/moment.js"&gt;&lt;/script&gt;

【讨论】:

  • 这个答案可以解决这个问题。您应该致力于从源头上修复它
  • @Phil 是的,它起作用了,我根据 vue 实现了这个。 import moment from "moment";convertFromNow(date) {return moment.utc(date).fromNow();`},`
【解决方案2】:

我对您的问题的理解是您需要获取用户的时区(通过他们的浏览器)。我将使用 moment 的 cdn 来演示这一点。

您需要同时拥有moment.jsmoment-timezone-with-data.js

<script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.js"></script>

然后使用这个函数:你的代码中的moment.tz.guess(); 应该给你用户的时区。

之后,您可以将获得的时区传递给您的 API,以检索该时区的正确时间。

另外,如果您使用的是 Carbon,您(可能)需要使用 setTimezone()

Carbon::parse($time)->setTimezone($tz);

其他人见:https://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

【讨论】:

    【解决方案3】:

    这是我在 Vanilla JavaScript 中的解决方案(不依赖于外部库,例如 moment.js 或 days.js)。

    诀窍是将“UTC”附加到日期字符串,然后再将其转换为 JavaScript Date 对象。

    const dateString = '2019-04-17 05:20:37';
    const localDate = new Date(`${dateString} UTC`);
    console.log(localDate)

    如果您在本地浏览器 (Chrome) 控制台上运行上述代码,它应该会根据您(或您的用户)本地时区打印时间。

    【讨论】:

    • “如果您在本地浏览器 (Chrome) 控制台上运行上述代码,它应该会根据您(或您的用户)本地时区打印时间。” - Firefox 将打印null
    • 谢谢@wentjun,您的解决方案帮助了我:) 但让我也可以在其他浏览器中进行测试。
    • @Andreas 你能告诉我你的 Firefox 版本吗?我相信这只适用于“旧”的 Firefox 浏览器
    • @DineshSuthar 我必须添加一个免责声明,该方法可能不适用于旧版 IE 浏览器。
    【解决方案4】:

    您的日期/时间字符串 "2019-04-17 05:20:37" 可能表示 UTC 时间,但 JavaScript 会将其解析为本地时间,这意味着时间将始终 错了。

    非常简单的答案是使用明确的格式,例如 ISO 8601 / Atom,例如

    "2019-04-17T05:20:37+00:00"
    

    Carbon 提供了一种简单的方法,您可以将其替换为 toDateTimeString()

    $user_details = [
        // snip
        'account_creation_date' => $userDetails->created_at->toAtomString(),
        'last_seen' => $lastSeen != null ? $lastSeen->toAtomString() : $userDetails->last_login->toAtomString(),
        // snip
    ];
    

    https://carbon.nesbot.com/docs/#api-commonformats

    【讨论】:

    • 感谢@Phil 指出这一改进。其实我不知道Carbon的这个toAtomString()方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多