Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save iamatypeofwalrus/d074d22a736d49459b15 to your computer and use it in GitHub Desktop.
Save iamatypeofwalrus/d074d22a736d49459b15 to your computer and use it in GitHub Desktop.
ActiveRecord: Store Milliseconds (or Microseconds) in Timestamps/Datetimes with Rails / MySQL

ActiveRecord: Store Milliseconds (or Microseconds) in Timestamps with Rails / MySQL

Milliseconds in your Timestamps.

We got 'em, you want 'em.

Why

Shit needs to be PRECISE

LICENSE

MIT

class MillisecondsMigration < ActiveRecord::Migration
# Include non default date stamps here
# Key :table_name
# value [:column_names]
# NOTE: only MySQL 5.6.4 and above supports DATETIME's with more precision than a second.
TABLES_AND_COLUMNS = {
# Your :table_names here
}
STANDARD_ACTIVE_RECORD_COLUMNS = [:created_at, :updated_at]
TABLE_AND_COLUMNS.each {|k,v| v.concat(STANDARD_ACTIVE_RECORD_COLUMNS)}
def up
TABLE_AND_COLUMNS.each do |table, columns|
columns.each do |column|
# MySQL supports time precision down to microseconds -- DATETIME(6)
change_column table, column, :datetime, limit: 3
end
end
end
def down
TABLE_AND_COLUMNS.each do |table, columns|
columns.each do |column|
echange_column table, column, :datetime
end
end
end
end
# Save this in config/initializers/WHATEVER.rb
class Time
# Ruby will complain that it has already initialzed DATE_FORMATS because it has...
DATE_FORMATS = {
# Where 3N is the number of places after the decimal (.)
# If you want microseconds change 3N to 6N
:db => '%Y-%m-%d %H:%M:%S.%3N'
}
end
@maletor
Copy link

maletor commented Feb 24, 2016

The initializer is not necessary with Rails 4.2.5. It just works with the correct database type DATETIME(6).
Additionally, adding this into an initializer will fix your migrations. All that is left after that is to make the change retroactive.

# Creates DATETIME(6) column types by default which support microseconds.
#
# Without it, regular DATETIME columns are created and Percona does not attach
# microseconds to the default DATETIME types. This has a rich history, refer to
# SQL Server DATETIME2.
ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::NATIVE_DATABASE_TYPES[:datetime][:limit] = 6

@MarkMurphy
Copy link

MarkMurphy commented May 6, 2016

I've created an updated gist with feedback from this thread.

See https://gist.github.com/MarkMurphy/93adca601b05acffb8b5601df09f66df

  • Fixes a typo or two
  • Migrates all table columns with type :datetime
  • Adds default :limit to AbstractMysqlAdapter::NATIVE_DATABASE_TYPES[:datetime] for future migrations.
  • Fixes "Time::DATE_FORMATS is already initialized"
  • Defaults precision to 6 instead of 3 because may as well.

@p1swk
Copy link

p1swk commented Feb 2, 2024

Is there a way to implement this in Teensy 4.1 or Arduino ? I am trying to develop a gunshot localization program to solve local gunfire at 2AM-4AM.

@kmooventhan98
Copy link

6 is working fine but if i keep 3 I am getting this error

ActiveRecord::StatementInvalid: Mysql2::Error: Incorrect datetime value: '2025-02-16 18:11:59.751.751251' for column 'created_at' at row 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment