POSO
@POSO

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

no implicit conversion of ActiveSupport::TimeWithZone into Integer

解決したいこと

ボタンAを押した時間-ボタンBを押した時間=何時間何分
でそれを導き出すアプリを製作中ですが、タイトルのエラーが出ました。

発生している問題・エラー

TypeError in hoge
no implicit conversion of ActiveSupport::TimeWithZone into Integer

該当するソースコード

def keisanhour
        keisan = Time.new(abotan) - Time.new(dbotan) + Time.new(bbotan) - Time.new(cbotan)
        keisanhour = keisan / 1.hour
end

自分で試したこと

資料がないので不明

0

11Answer

資料がないので不明

エラーの内容で十分な情報を得られていると思います。エラーの内容で検索したり、処理を分割してエラーが出てそうな所を特定したりしましたでしょうか?

Time.newに渡している引数が怪しい気がします。
「abotan」などの型は何になっているでしょうか?エラーの通り整数の形で渡してあげられているでしょうか?

0Like

Comments

  1. @POSO

    Questioner

    abotanの型はtimestampです、時間なので
  2. 元々時間の型になっているのであれば、、Time.new()をかまさずそのまま計算できませんか?
  3. @POSO

    Questioner

    undefined method `-' for "11:40":String
    このようなエラーが出ます
  4. abotanの型は時間ではなく、"hh:mm"の文字列のようですね。

    require "time"を記述したうえで、Time.parse(abotan)と記述して時間に変換できないでしょうか?
  5. @POSO

    Questioner

    require "time"はどこに書きますか?defendの一番上でしょうか
  6. ライブラリの読み込みは、コードの一番上にまとめて書いておいていいと思います。
  7. @POSO

    Questioner

    no implicit conversion of ActiveSupport::TimeWithZone into String
    が出ました
    class TimerDecorator < Draper::Decorator
    require "time"
    delegate_all

    end
    内部は省略しましたがこのようになっています
  8. abotan~dbotanの4つの変数の型すべて教えてもらってもいいでしょうか?
    型は.classで確認できます。
  9. @POSO

    Questioner

    おそらくIntegerがと思います
    捕捉ですが、html側にkeisan側の表記をなくし(abotan単体など)のみを出力しようとすると成功します
  10. これまでの内容から、abotan~dbotanで型が統一されてないような気がします。
    時間型になっていないものがあれば、その変数をTimeWithZoneに変換してあげれば、問題なく時間の加算減算ができると思います。

    >おそらくIntegerがと思います
    おそらくではなく、すべての変数の型を確実に確認していただいてもよろしいでしょうか?
  11. @POSO

    Questioner

    TimeWithZoneに変換
    この方法を教えてください
    変数の型を確実に確認
    これはわかりません
  12. 「'文字列'.in_time_zone」でTimeWithZoneに変換できると思います。

    型の確認方法は先に載せた通り、「'変数名'.class」で確認できます。
    「abotan.class」というようにすべての変数の型を確認してみてください。時間型でないものがあれば、時間型に変換してあげる必要があります。
  13. @POSO

    Questioner

    irb(main):003:0> 'abotan'.class
    => String
    irb(main):004:0> 'bbotan'.class
    => String
    irb(main):005:0> 'cbotan'.class
    => String
    irb(main):006:0> 'dbotan'.class
    => String
    stringです
    irb(main):007:0> 'created_at'.class
    => String
    クリエイトもstringです
  14. であれば、該当の行でこのエラーが出ないような気がします。
    「no implicit conversion of ActiveSupport::TimeWithZone into Integer」

    型の確認をしたのは、このメソッド(keisanhour)に入ってからでしょうか?
    このメソッドに入る前に型変換されているような場所はないですか?
  15. @POSO

    Questioner

    型の確認をしたのは、このメソッド(keisanhour)に入ってからでしょうか?
    このメソッドに入る前に型変換されているような場所はないですか?
    ないはずです、もしあったらこの前のdbからデータを直接持ってくるときにエラーが起こると思います
    <% @timers.each do |timer| %>
    <tr>
    <td><%= timer.created_at %></td>
    <td><%= timer.yobi %></td>
    <td><%= timer.abotan %></td>
    <td><%= timer.bbotan %></td>
    <td><%= timer.keisanhour %></td>
    <td><%= timer.keisancd %></td>
    <td><%= timer.keisanda %></td>
    </tr>
    <% end %>
    ちなみにhtmlではこうなっています
  16. DBから値を取得したタイミングで String → TimeWithZoneの型変換が発生していませんか?

    また、abotan、bbotan、cbotan、dbotanはすべてDBから取得した日付を格納していますか?
  17. @POSO

    Questioner

    def abotan
    object.syussya.strftime("%H:%M")
    end
    def bbotan
    object.taisya.strftime("%H:%M")
    end
    html表示時に表記変換を行ってはいますが、DBから取得したものです
    rails cから打ち込み、それを出力しています
  18. abotanとbbotanについて記載がありますが、cbotanとdbotanもまったく同じ記述がある認識でよろしいですか?
  19. 話がややこしくなってきたので、一端最初から話を整理しますね。

    ①まずPOSO様自身は以下のエラーの意味を理解していますか?
    「no implicit conversion of ActiveSupport::TimeWithZone into Integer」

    ②このエラーが出ているのは、下記記述が原因であることは間違いないですか?
    keisan = Time.new(abotan) - Time.new(dbotan) + Time.new(bbotan) - Time.new(cbotan)
  20. @POSO

    Questioner

    ①まずPOSO様自身は以下のエラーを意味を理解していますか?
    「no implicit conversion of ActiveSupport::TimeWithZone into Integer」
    わかりません
    ②このエラーが出ているのは、下記記述が原因であることは間違いないですか?
    keisan = Time.new(abotan) - Time.new(dbotan) + Time.new(bbotan) - Time.new(cbotan)
    これらの計算式を消すと正常に動きます
  21. ありがとうございます。

    「no implicit conversion of ActiveSupport::TimeWithZone into Integer」
    は、TimeWithZone型からInteger型への暗黙的型変換に失敗しているということです。

    そこで、該当行でInteger型への暗黙的型変換が起こると思われる部分は、Time.new()です。
    Time.new()は引数に数値を渡すと日付型に変換してくれるためです。

    date = Time.new(2021,9,1,21,32,32)
    puts date
    # 2021-09-01 21:32:32



    以上から、Time.new()の引数として渡しているabotan~dbotanはTimeWithZone型になっているのではないかと思いました。
    そこで、Time.new()を消して以下のような記述をしてもらうと、「undefined method `-' for "11:40":String」のエラーが出たということで間違いないですか?
    keisan = abotan - dbotan + bbotan - cbotan
  22. @POSO

    Questioner

    そこで、Time.new()を消して以下のような記述をしてもらうと、「undefined method `-' for "11:40":String」のエラーが出たということで間違いないですか?
    keisan = abotan - dbotan + bbotan - cbotan
    はい、あってます
  23. ありがとうございます。
    ということは、abotan~dbotanの4つの中で少なくとも1つは型がTimeWithZone型になっており、'-'の後ろにあるdbotanかcbotanのどちらかがString型である可能性が高いです。

    ですので、以下の記述の直前でabotan~dbotanすべての型を確認して欲しいです。
    keisan = abotan - dbotan + bbotan - cbotan

    ※日付の足し算は多分エラーになるので、すべて日付型だったとしても以下のようにかっこが必要な気がしています。
    keisan = (abotan - dbotan) + (bbotan - cbotan)


    あっあと、多少「暗黙的型変換」など詳しい説明を省いている部分もあるので、ちゃんと理解できていない部分があれば後ほどご自身で調べて腹落ちさせておいてください。
  24. @POSO

    Questioner

    >ですので、以下の記述の直前でabotan~dbotanすべての型を確認して欲しいです。
    keisan = abotan - dbotan + bbotan - cbotan
    stringとは違うんですか?確認の仕方は全くわかりません
    >※日付の足し算は多分エラーになるので、すべて日付型だったとしても以下のようにかっこが必要な気がしています。
    keisan = (Time.new(abotan) - Time.new(dbotan)) + (Time.new(bbotan) - Time.new(cbotan))
    こうですか?
  25. >stringとは違うんですか?
    おそらくですが、StringのものとTimeWithZoneのものとが混合している状態です。

    >確認の仕方は全くわかりません
    普段デバッグはどのようにされているのでしょうか?デバッグ実行できる環境であれば、ブレークポイントを置いて確認などできるとすぐ確認などできると思うのですが…

    それが難しいのであれば、
    DBから取得した値をWeb画面に表示したりはできている状態ですか?

    それができているのであれば、適当に4つ領域を用意しておいて、keisanhourメソッドに入った最初の処理で、abotan.class、bbotan.class、cbotan.class、dbotan.classを画面に表示させれば確認できると思います。
  26. それも難しければ、以下の記述で実行したときそれぞれエラーが出るか試してもらってもいいですか?
    ①keisan = abotan - dbotan
    ②keisan = bbotan - cbotan
  27. @POSO

    Questioner

    DBから取得した値をWeb画面に表示したりはできている状態ですか?
    計算なしなら可能です(abotan単品など)
    それも難しければ、以下の記述で実行したときそれぞれエラーが出るか試してもらってもいいですか?
    ①keisan = abotan - dbotan
    ②keisan = bbotan - cbotan
    no implicit conversion of ActiveSupport::TimeWithZone into Integer
    やはりこのエラーが出ます
  28. ①と②両方同じエラーが出るということですね。

    keisanhourを下の①、②のような記述に変更したらどうなりますか?


    def keisanhour
     keisanhour= abotan
    end


    def keisanhour
     keisanhour= dbotan
    end
  29. @POSO

    Questioner

    問題なく表示されます
    が下だと
    def abotan
    object.abotan.strftime("%H:%M")
    end
    これに関する記述がされてないので
    021-08-31 11:00:00 UTC
    こうなります
  30. @POSO

    Questioner

    全てobject.abotan.strftime("%H:%M")を記述することで成立しました、
    最後に、
    def keisanhour
    keisantime = Time.new(cbotan) - Time.new(bbotan)
    end
    これを分時間に表記を変換したいのですが、それを教えてください
  31. 現状、上記の記述で秒数の差が出ているということでお待ちがないでしょうか?
  32. @POSO

    Questioner

    分時間表記とは1:30
    のような感じです
  33. @POSO

    Questioner

    はいそうでさう
  34. えーと、どこまで自分でお調べしたり実装しようとしてみたりしましたか?
    ここまで実装してみたというソースがあればアドバイスしやすいと思います。
  35. @POSO

    Questioner

    def keisanhour
    keisantime = Time.new(cbotan) - Time.new(bbotan)
    object.breaks.strftime("%H:%M")
    end
    今までのようにこう書きましたが、エラーが出ました、おそらく秒換算状態なので、こうなっていると思います
    秒表示から時間分表示できれば完了のはずです

秒表示から時間分表示できれば

単純に0時0分の日付を用意して、秒数を足して、時間と分だけ表示すれば実現できると思います。

image.png

0Like

Comments

  1. @POSO

    Questioner

    def keisanmini
    keisanhour = Time.new(bbotan) - Time.new(abotan)
    keisanday = Time.new(1) + Time.new(keisanhour)
    object.keisanday.strftime("%H:%M")
    end

    TypeError time + time?
    型がおなじでないというエラーが起きました

秒数を時間に変換して足す必要はないです。秒数のまま足してあげてください。

-keisanday = Time.new(1) + Time.new(keisanhour)
+keisanday = Time.new(1) + keisanhour

TypeError time + time?

これは型がおなじでないエラーではなくて、時間型と時間型の足し算はできないですよというエラーです。時間は差を求める演算しかできないので、時間型同士は引き算しかできません。

変数名も少し気になりました。可読性あげるために適切な変数名にしておかないとのちのちに響いてきます。
修正するとしたらこんな形でしょうか。

def get_working_time
    diff_sec= Time.new(bbotan) - Time.new(abotan)
    diff_time = Time.new(1) + diff_sec
    object.diff_time.strftime("%H:%M")
end
0Like

Comments

  1. @POSO

    Questioner

    def keisanmini
    keisanhour = Time.new(bbotan) - Time.new(abotan)
    keisanday = Time.new(1) + keisanhour
    object.keisanday.strftime("%H:%M")
    end
    こうすると
    NoMethodError undefined method `keisanday'
    と出ます

とりあえず、ガイドを見てみてください。

htmlに@model.keisanminiのような記載があれば、以下のような記述でページに表示されませんか?

def keisanmini
    diff_sec= Time.new(bbotan) - Time.new(abotan)
    diff_time = Time.new(1) + diff_sec
    keisanmini = diff_time.strftime("%H:%M")
end

もしくは

def keisanmini
    diff_sec= Time.new(bbotan) - Time.new(abotan)
    diff_time = Time.new(1) + diff_sec
    diff_time.strftime("%H:%M")
end
0Like

Comments

  1. @POSO

    Questioner

    html側に表示する際にmodel名が必要なのですね
    decotratorで作っている場合ではどうしたらいいでしょう
  2. @POSO

    Questioner

    <%= form_with model: @timers[0],local: true do |f| %>
    <div class="timechart">
    <% @timers.each do |timer| %>
    <tr>
    <td><%= timer.created_at %></td>
    <td><%= timer.yobi %></td>
    <td><%= timer.abotan %></td>
    <td><%= timer.dbotan %></td>
    <td><%= timer.keisanhour %></td>
    <td><%= timer.keisanmini %></td>
    <td><%= timer.keisanhour %></td>
    </tr>
    <% end %>
    modelは出ており、dbからそのまま持ってきたものは問題なく表示され、かつ数値も変化しています
    計算後、
    diff_time = Time.new(1) + diff_sec
    diff_time.strftime("%H:%M")
    これらを追加したらエラーが起こりました、html側の記述ミスか、計算が違うのか、わかんないです
  3. その情報だけじゃこちらもわからないです。

    エラーの内容と、どのファイルにどういう記述があるのか、
    また、そのエラーで調べてどこまでわかったか、どういうことを試したかも教えていただいてもいいですか?
  4. @POSO

    Questioner

    @timer.keisanhour
    にすると
    NoMethodError undefined method `keisanhour' for nil:NilClass
    になります
    timer.keisanhour
    にするyと
    NoMethodError undefined method `keisanday'
    下だと計算がありません、と出て上だとそれはからです、と出ます
    下だと計算を削ると秒数が出てくるので、下の計算をどうにかすれば動くはずです
  5. 秒数を表示するのはできたんですよね?

    秒数表示できている状態のソースを見せてもらってもいいですか?
  6. @POSO

    Questioner

    def keisanmini
    keisanhour = Time.new(bbotan) - Time.new(abotan)
    end
    <td><%= timer.keisanmini %></td>
    こうです、他の計算もこうでネス
  7. ①この記述で「keisanmini」と「keisanhour」のどちらに秒数が表示されていますか?

    ②「keisanmini」の定義のなかで「keisanhour」に値を代入している意図って何かありますか?

    ③def keisanhourの記述はどこかにありますか?あれば、どんな記述していますか?
  8. @POSO

    Questioner

    ①この記述で「keisanmini」と「keisanhour」のどちらに秒数が表示されていますか? 
    html上ではheisanminiで表示されています
    ②「keisanmini」の定義のなかで「keisanhour」に値を代入している意図って何かありますか?
    時間表示にする、というわけでhourにしました
    ②「keisanmini」の定義のなかで「keisanhour」に値を代入している意図って何かありますか?
    ないです
def keisanmini
    diff_sec= Time.new(bbotan) - Time.new(abotan)
    diff_time = Time.new(1) + diff_sec
    keisanhour = diff_time.strftime("%H:%M")
end

この記述でどうなりますか?

あと、ほかにいくつか質問いいですか?

①この記述で「keisanmini」と「keisanhour」のどちらに秒数が表示されていますか? 
html上ではheisanminiで表示されています

①keisanhourって現状何が表示されているのでしょうか?

②rubyという言語についてどこまで学習されていますか?
変数や型、メソッドなど基本的な要素はどのくらい勉強されていますでしょうか?
なんとなくの理解度でいいのでお聞かせください。

0Like

Comments

  1. @POSO

    Questioner

    ①keisanhourって現状何が表示されているのでしょうか?
    これは計算用のメソッドなので、特に意味はありません
    ②rubyという言語についてどこまで学習されていますか?
    変数や型、メソッドなど基本的な要素はどのくらい勉強されていますでしょうか?
    なんとなくの理解度でいいのでお聞かせください
    この間SEとして入社し、現在勉強中です、コードを書きながら勉強しています
  2. ①私が記載した上記コードの結果はどうなりましたか?

    ②「これは計算用のメソッドなので、特に意味はありません」とありますが、htmlの要素にも「keisanhour」を置いているようです。「「keisanhour」」部分には現在何も表示されていないということでしょうか?
    メソッドとして利用するためだけなのであれば、htmlに書く必要ってあるのでしょうか?

    ③今作成しているものは、研修の課題か何かでしょうか?
  3. @POSO

    Questioner

    def keisanmini
    diff_sec= Time.new(bbotan) - Time.new(abotan)
    diff_time = Time.new(1) + diff_sec
    keisanhour = diff_time.strftime("%H:%M")
    end
    これを入れたところエラーは出ませんdしたが、計算結果が00:00になりました、消すと秒数が表示されるのにです
  4. @POSO

    Questioner

    ②「これは計算用のメソッドなので、特に意味はありません」とありますが、htmlの要素にも「keisanhour」を置いているようです。「「keisanhour」」部分には現在何も表示されていないということでしょうか?
    メソッドとして利用するためだけなのであれば、htmlに書く必要ってあるのでしょうか?
    keisanhourの位置に秒数が表示されています
    ③今作成しているものは、研修の課題か何かでしょうか?
    そうです

①この記述で「keisanmini」と「keisanhour」のどちらに秒数が表示されていますか? 
html上ではheisanminiで表示されています

②「これは計算用のメソッドなので、特に意味はありません」とありますが、htmlの要素にも「keisanhour」を置いているようです。「「keisanhour」」部分には現在何も表示されていないということでしょうか?
メソッドとして利用するためだけなのであれば、htmlに書く必要ってあるのでしょうか?
keisanhourの位置に秒数が表示されています

①結局、秒数は「keisanmini」と「keisanhour」どちらに表示されているのでしょうか?

②研修の課題として行っているのであれば、rubyについて体系的に学べる、社内の初学者向けの資料とかってないのでしょうか?

0Like

Comments

  1. @POSO

    Questioner

    <td><%= timer.keisanhour %></td>
    これに表示されています

    資料も見ながらやっています
  2. 全体を把握したいので、modelとviewとdecoratorのコードを載せていただいてもいいですか?
    回答への返信だとインデント崩れてみずらいので、新しい回答としてソースを埋め込んで投稿してもらえますか?
  3. @POSO

    Questioner

    やりました

'''
class Timer < ApplicationRecord
end
'''
'''
class TimerDecorator < Draper::Decorator
delegate_all
require "time"
def created_at
object.created_at.strftime("%-m/%-d")
end
def abotan
object.abotan.strftime("%H:%M")
end
def bbotan
object.bbotan.strftime("%H:%M")
end
def cbotan
object.breaks.strftime("%H:%M")
end
def dbotan
object.breakf.strftime("%H:%M")
end
def keisanmini
keisantime = Time.new(dbotan) - Time.new(cbotan)
end
end
'''
'''
<% @timers.each do |timer| %>

<%= timer.created_at %> <%= timer.abotan %> <%= timer.bbotan %> <%= keisanmini %> <% end %> '''
0Like

keisanminiのdefの部分、以下の記載でどう表示されるようになりますか?

def keisanmini
    keisantime = Time.new(dbotan) - Time.new(cbotan)
    (Time.new(1) + keisantime).strftime("%H:%M")
end
0Like

Comments

  1. @POSO

    Questioner

    00:00です
def keisanmini
    Time.new(dbotan) - Time.new(cbotan)
end

これだと各行異なる秒数が表示されますか?

0Like

Comments

  1. @POSO

    Questioner

    def keisanmini
    Time.new(dbotan) - Time.new(cbotan)
    end
    はい、abotanとbbotanを比べた場合でも表示には失敗しません

もうすでに試されてるかもしれませんが、以下の2パターンだとどうなりますか?

def keisanmini
    Time.new(1)
end
def keisanmini
    keisantime = Time.new(dbotan) - Time.new(cbotan)
    Time.new(1) + keisantime
end
0Like

Comments

  1. @POSO

    Questioner

    上だと
    0001-01-01 00:00:00 +0900
    下は
    0002-01-02 00:00:00 +0900
    cbotanの中身は2021-09-03 12:47:04
    dbotanの中身は2021-09-03 13:47:04
    です
  2. なるほどー。
    1つ前の秒数表示されてる時は、何秒って表示されていましたか?
  3. @POSO

    Questioner

    (dbotan)-(cbotan)は31622400.0です

    追記ですが
    bbotan-abotanは315619200.0
    (bbotan-dbotan)+(abotan-cbotan)は283996800.0

    abotanの中身は2021-09-03 07:47:04
    bbotanの中身は2021-09-03 17:47:04
    なので計算式自体はあっています
  4. 31622400.0秒はちょうど366日ですね。
    明らかに秒数がおかしいので、そのあたり見直された方が良さそうかと。
  5. @POSO

    Questioner

    0002-01-02 00:00:00 +0900
    つまりこの計算式はあっているということですね
    db内をいじってdbotanの日付を9/5にしてみましたが、31622400.0秒が変わりませんでした
    def abotan
    object.abotan.strftime("%H:%M")
    end
    def bbotan
    object.bbotan.strftime("%H:%M")
    end
    def cbotan
    object.cbotan.strftime("%H:%M")
    end
    def dbotan
    object.dbotan.strftime("%H:%M")
    end
    こう定義した関係で、年日という概念を失ったため計算がおかしくなっている、もう別の計算式としないとうまくいかないという可能性がありそうです
  6. @POSO

    Questioner

    全部%-m/%-d%H:%Mにしましたが、計算結果が0.0になってしまいました。。。
  7. @POSO

    Questioner

    差を8時間にすると
    252460800
    という結果が出ました
  8. @POSO

    Questioner

    差が5分だと0.0 です

原因わかりました。
気づくのが遅くなってすみません。

require "time"
d = Time.new(2021,9,1,8,33,32).strftime("%H:%M")
puts d
puts Time.new(d)
puts Time.parse(d)

image.png

「時:分」の文字列をTime.newで時刻に変換するとおかしな日付になってしまいます。
一度「時:分」にした文字列を時刻に戻す場合は、以前お伝えしたTime.parseを使ってください。

0Like

Comments

  1. @POSO

    Questioner

    完了しました
    長い間、本当にありがとうございました。
  2. 解決してよかったです。
    なかなか根本原因を特定できず、申し訳ありませんでした。
    引き続きプログラミング頑張ってください!

Your answer might help someone💌