besukosan
@besukosan

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【Rails + JS + Ajax】Railsの日時(UTC)を現在地の時刻で表示

解決したいこと

保存されたRailsの各データの日時(UTC)を、現示地の時刻に変換して表示したい。

試したこと

var sec = -60*(new Date().getTimezoneOffset());

JSで現在地とUTCとの時差(秒)を取得しました。
これをRailsの各データの日時(UTC)に足して現在地時刻にて表示したい考えております。

問題箇所

上記コードにて取得した時差(秒)を、Railsの各日時データに足す方法が分からずにおります。

ネット上には「JSの値はAjaxでJSON形式に変換して、Railsのコントローラに埋め込む」といった方法が散見されます。
ですが今回は発火させるイベントはなく、デフォルトの値としてRailsに渡したいです。

また一度取得した時差をsessionとしてブラウザにて保持し、その後は全ての日時データに時差を足した上で表示したいと考えております。

こういった手法が現在地の時刻表示方法として一般的かは分かりかねますが、私なりに考え辿り着きました。
もしご存知の方がいらっしゃいましたらご教示頂けますと幸いです。

0

3Answer

フロント

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>besukosan</title>
  </head>
  <body>
    <h1 id="hoge"></h1>
    <script src="index.js"></script>
  </body>
</html>
index.js
const utc = new Date().getTime();
const sec = -60 * 1000 * new Date().getTimezoneOffset();

// 適切に変える
const url = 'http://localhost:3000/hello';

fetch(url, {
  method: 'post',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ time: new Date(utc + sec) }),
})
  .then(async res => {
    const _ret = await res.json();
    const _now = new Date(_ret['time']);

    const _time = `${_now.getUTCFullYear()}-${
      _now.getUTCMonth() + 1
    }-${_now.getUTCDate()}-${_now.getUTCHours()}:${_now.getUTCMinutes()}:${_now.getUTCSeconds()}`;

    document.getElementById('hoge').textContent = _time;
    console.log(_time);
  })
  .catch(console.error);

バックエンド(一部省略)

app/controllers/hello_controller.rb
class HelloController < ApplicationController
  protect_from_forgery except: :helo

  def helo
    time_i = Time.parse(params["time"]).to_i
    date = Time.at(time_i).utc

    p date.year.to_s + "-" + date.mon.to_s + "-" + date.day.to_s + "-" + date.hour.to_s + ":" + date.min.to_s + ":" + date.sec.to_s

    render json: { time: params["time"] }
  end
end
config/application.rb
# 省略

module Myproject
  class Application < Rails::Application
   # 省略
 
    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins "*"
        resource "*",
          headers: :any,
          methods: [:get, :post, :options, :head]
      end
    end
  end
end
config/routes.rb
Rails.application.routes.draw do
  post "/hello", to: "hello#helo"
end
..Gemfile
# 省略
gem "rack-cors"
# 省略
1Like

Comments

  1. @besukosan

    Questioner

    大変ご丁寧にご回答下さったのに、返答が遅くなり申し訳ございません。

    今回は、cookieを用いる事で直面していた問題を解決することが出来ました。
    もしそれだと今後新たな問題が発生した場合は、改めて@yuzuru2様の方法を検討したいと存じます。
    今後とも何卒よろしくお願い致します。
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>besukosan</title>
  </head>
  <body>
    <h1 id="hoge"></h1>
    <script src="index.js"></script>
  </body>
</html>
index.js
const utc = new Date().getTime();
const sec = -60 * 1000 * new Date().getTimezoneOffset();

const now = new Date(utc + sec);

const time = `${now.getUTCFullYear()}-${
  now.getUTCMonth() + 1
}-${now.getUTCDate()}-${now.getUTCHours()}:${now.getUTCMinutes()}:${now.getUTCSeconds()}`;

document.getElementById('hoge').textContent = time;
console.log(time);
0Like

Comments

  1. @besukosan

    Questioner

    早速ご回答頂きありがとうございます。

    <h1 id="hoge"></h1>とconsoleにそれぞれ現在地の時刻が出ますが、
    これらをRailsの値として扱う方法はご存知でしょうか。
    そこで行き詰まっております。。

最終的に以下のようにcoockieを用いて時差「@tz」を定義することで解決いたしました。
(参照元:https://gist.github.com/bkeepers/320844#file-application-js-L1)

application.js
//タイムゾーン取得(取得した時差「tz」はapplication_controller.rbで@tzとして扱う)
jQuery(function() {
  $.cookie('tz', (new Date()).getTimezoneOffset());
});
application_controller.rb
def set_timezone
	@tz = cookies[:tz].to_i * 60
end

あとは任意の場所でUTC時間のデータから「@tz」を引けば現地時刻になります。

users_controller.rb
#例)
@user = User.find_by(params[:id])
@user_created_at_local_time = @user.created_at - @tz
0Like

Your answer might help someone💌