Is there a way to change Rails default timestamps to Y-m-d H:i:s (instead of Y-m-d H:i:s.u) or have laravel ignore decimal portion of Y-m-d H:i:s.u?

后端 未结 3 454
萌比男神i
萌比男神i 2021-01-25 03:49

I have two applications using the same postgres DB. A laravel application and a rails application. The current data in the DB is in Y-m-d H:i:s format but whenever

相关标签:
3条回答
  • 2021-01-25 04:03

    In Laravel/PHP, you can convert DateTime with millisecond to without millisecond using below function:

    $date = date('Y-m-d H:i:s.u');
    echo date('Y-m-d H:i:s', strtotime($date));
    

    In Rails, you can update your time object before sending it to the database, as mentioned below:

    time.change(:usec => 0)
    
    0 讨论(0)
  • 2021-01-25 04:09

    Solution in the Rails side

    It seems ActiveRecord used in Rails (5.2) automatically adds decimal seconds down to 1 msec in saving created_at and updated_at or any other Timestamp columns in the DB that accept sub-seconds, as defined in the file active_record/connection_adapters/abstract/quoting.rb

    A work around is this. Add this line at a top level in any of the files which would be always read by Rails when accessing a model (such as, ApplicationRecord model file).

    Time::DATE_FORMATS[:db] = '%Y-%m-%d %H:%M:%S.000000000'
    
    module ActiveRecord::ConnectionAdapters::Quoting
      alias_method :quoted_date_orig, :quoted_date if ! self.method_defined?(:quoted_date_orig)
    
      def quoted_date(*rest, **kwd)
        quoted = quoted_date_orig(*rest, **kwd)
        quoted.sub(/(\.\d*)\.\d{6}$/, '\1')
      end
    end
    

    You can confirm it from Rails console, after creating a new record,

    MyModel.last.created_at.nsec  # => 0
    

    or simply access the DB directly to see it.

    Warning

    This change affects not only created_at and updated_at but also all the other timestamp columns in the DB. I think you can still save a value to msec (or nsec) precision to such a column by setting a String as opposed to a Time instance to your Model instance like my_model.col_msec_desired = "2018-01-02 03:04:05.678"; then Time::DATE_FORMATS[:db] would not be referenced in saving the record.

    Potential solution in the Laravel side

    It may be tricky at the time of writing (2018-10-18), but a work seems to be in progress, according to a very recent Laracast post by cmbertsch01

    (Note: a major update made a day after from the original post, following the comment.)

    0 讨论(0)
  • 2021-01-25 04:13

    you can set Time::DATE_FORMATS[:db] in application.rb

    Time::DATE_FORMATS[:db] = "Y-m-d H:i:s.u"
    

    looks more at strftime format

    0 讨论(0)
提交回复
热议问题