Roo에서 가져온 Excel 날짜 및 시간 데이터가 잘 반영되지 않음

안녕하세요

오류가 발생한 배경


roo 를 사용하여 Excel 날짜 및 시간 데이터를 캡처하도록 개발했습니다.
어느 정도 완성되어 확인하려고 하면 아래와 같은 에러가 나왔습니다.
아마, in_time_zone 메소드가 integer 형에 대응할 수 없다고 하는 에러가 아닐까 생각했습니다.
아래에- エラーメッセージが出た部分- 対応するメソッド(controller)- エラーが発生したファイル를 싣고 있습니다.



app/controller/ir/meeting_logs_controller.rb
  def time_from_excel_date_time(excel_date, excel_time)
    date = excel_date.in_time_zone

    if excel_time.is_a?(String)
      time = excel_time.to_time
      hour = time.hour
      minute = time.min
    elsif excel_time.is_a?(Integer)
      hour = (excel_time / 3600)
      minute = (excel_time % 3600 / 60)
    end

    date + hour.hour + minute.minute
  end

평상시 캡처하는 Excel 파일(해당 개소만)


id
날짜
시작 시간



12/9
1:00

12/8
1:00

11/27
1:00

11/26
1:00


이번 에러가 발생한 엑셀 파일(해당 개소만)


id
날짜
시작 시간



12월 9일
1:00

12월 8일
1:00

11월 27일
1:00

11월 26일
1:00


원인



위의 부분을 봐 주시면 알 수 있듯이 日付 의 단락지어진 부분이 / 인가 月日 의 차이에 의한 것이었습니다.
이 부분이 다르면,/ 그러면 그대로(String형),月日 그러면 숫자(Integer형)
가 변수로서 받아들여지기 때문에, String형 밖에 대응하고 있지 않은 메소드로 에러가 발생해 버렸습니다.

개선책



그래서 controller를 다시 작성했습니다.

app/controller/ir/meeting_logs_controller.rb
  def time_from_excel_date_time(excel_date, excel_time)
  EXCEL_EPOCH = 2209078800
  TICKS_PER_DAY = 60 * 60 * 24
    if excel_date.is_a?(String) || excel_date.is_a?(Date)
      date = excel_date.in_time_zone
    elsif excel_date.is_a?(Integer)
      # 日付が漢字の場合、integer型で受け取る => 1899/12/31 からどれくらいの日数がたったかを表している
      # Unixのゼロタイム(基準)が "1970/1/1" に設定されている為、下記ステップで日付を求める
      # 1. TICKS_PER_DAY をかけて、1899/12/31 からどれくらいの秒数がたったかを計算
      # 2. 1から EXCEL_EPOCH 秒をを引き、1970/1/1 からどれくらいの秒数がたったかを計算

      unix_timestamp = excel_date * TICKS_PER_DAY - EXCEL_EPOCH
      date = Time.at(unix_timestamp).to_datetime - 8.hours - 1.day
    end

    if excel_time.is_a?(String)
      time = excel_time.to_time
      hour = time.hour
      minute = time.min
    elsif excel_time.is_a?(Integer)
      hour = (excel_time / 3600)
      minute = (excel_time % 3600 / 60)
    end

    date + hour.hour + minute.minute
  end

excel에서 가져온 날짜의 변수가 들어 있는 excel_date 에 대해 if문에서 String형과 Integer형으로 나누어 처리를 달리기로 했습니다.
또, unix_timestamp 의 부분이 복잡하므로 아래에 설명을 하고 싶습니다.

유닉스와 엑셀



이 컨트롤러의 설명은 주로 unix와 엑셀 기준의 시간을 맞추기 위해 썼습니다.
코멘트 아웃에서도 쓰고 있습니다 만,
excel은 기준이 1899/12/31이므로 돌아오는 변수는 1899/12/31から何日たっているか를 나타냅니다.
그러나 Ruby에 한정되지 않고 unix를 기준으로 하는 프로그래밍 언어는 1970/1/1(ゼロタイム) 를 기준으로 작동합니다.
그래서 Excel 변수를 unix 기준에 맞추기 위해
unix_timestamp = excel_date * TICKS_PER_DAY - EXCEL_EPOCH

의 설명을하고 있습니다.

마지막으로



이번 내 첫 투고이므로 이르지 않는 점이 있다고 생각합니다만,
저 나름대로 열심히 노력했을 거예요. 웃음
만약, 뭔가 어드바이스등 있으면 꼭 가르쳐 주셨으면 합니다!

좋은 웹페이지 즐겨찾기