--- /dev/null
+*~
+*.log
+*.db
+
--- /dev/null
+TimestampsAsString
+=================
+
+Description goes here
--- /dev/null
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+require 'rake/gempackagetask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the timestamps_as_string plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the timestamps_as_string plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'TimestampsAsString'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
+
+PKG_FILES = FileList[
+ 'lib/*.rb',
+ 'rails/init.rb',
+ 'spec/*'
+]
+spec = Gem::Specification.new do |s|
+ s.name = 'timestamps_as_string'
+ s.version = '0.0.1'
+ s.author = 'Good-Day, Inc.'
+ s.email = 'info@good-day.co.jp'
+ s.homepage = 'http://www.good-day.jp/'
+ s.platform = Gem::Platform::RUBY
+ s.summary = 'Add functionarity of timestamps as string'
+ s.files = PKG_FILES.to_a
+ s.require_path = 'lib'
+ s.has_rdoc = false
+ s.extra_rdoc_files = ['README']
+end
+
+Rake::GemPackageTask.new(spec) do |pkg|
+ pkg.gem_spec = spec
+end
--- /dev/null
+require "rubygems"
+require "active_record"
+
+# テーブルに格納されている時刻を透過的に扱うためのモジュール。
+module TimestampsAsString
+ def self.included(base) #:nodoc:
+ super
+
+ base.alias_method_chain :create, :string_timestamps
+ base.alias_method_chain :update, :string_timestamps
+
+ base.record_timestamps = false
+ base.class_inheritable_accessor :record_string_timestamps, :instance_writer => false
+ base.record_string_timestamps = true
+
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods
+ def timestamps_as_string
+ class_eval do
+ alias :created_at :created_at_with_string_timestamps
+ alias :updated_at :updated_at_with_string_timestamps
+ end
+ end
+ end
+
+ # 作成の際にカラム <tt>created_at</tt> や <tt>updated_at</tt> に日時を内部表現で格納する。
+ def create_with_string_timestamps #:nodoc:
+ if record_string_timestamps
+ s = Time.now.utc.strftime("%Y%m%d%H%M%S")
+ write_attribute("created_at", s) if self.class.column_names.include?("created_at") && created_at.nil?
+ write_attribute("updated_at", s) if self.class.column_names.include?("updated_at")
+ end
+ create_without_string_timestamps
+ end
+
+ # 更新の際にカラム <tt>updated_at</tt> に日時を内部表現で格納する。
+ def update_with_string_timestamps #:nodoc:
+ if record_string_timestamps
+ s = Time.now.utc.strftime("%Y%m%d%H%M%S")
+ write_attribute("updated_at", s) if self.class.column_names.include?("updated_at")
+ end
+ update_without_string_timestamps
+ end
+
+ # <tt>created_at</tt> を置き換える。
+ # 内部表現から時刻オブジェクトへ変換して返す。
+ def created_at_with_string_timestamps
+ return convert_from_string_timestamp(read_attribute_before_type_cast("created_at"))
+ end
+
+ # <tt>updated_at</tt> を置き換える。
+ # 内部表現から時刻オブジェクトへ変換して返す。
+ def updated_at_with_string_timestamps
+ return convert_from_string_timestamp(read_attribute_before_type_cast("updated_at"))
+ end
+
+ module_function
+
+ def convert_from_string_timestamp(str)
+ if str.nil?
+ return nil
+ elsif /\A(....)(..)(..)(..)?(..)?(..)?\z/ =~ str
+ return Time.utc(*$~.captures.compact).localtime
+ else
+ raise ArgumentError, "invalid timestamp #{str.inspect}"
+ end
+ end
+
+end
+
+ActiveRecord::Base.class_eval do
+ include TimestampsAsString
+end
--- /dev/null
+require "timestamps_as_string"
--- /dev/null
+# desc "Explaining what the task does"
+# task :timestamps_as_string do
+# # Task goes here
+# end
--- /dev/null
+require "test/unit"
+require "timestamps_as_string"
+
+class TimestampsAsStringTest < Test::Unit::TestCase
+ def assert_convert_from_string_timestamp(expected, actual)
+ actual = TimestampsAsString.convert_from_string_timestamp(actual)
+ assert_equal(expected, actual)
+ end
+ def test_convert_from_string_timestamp
+ assert_convert_from_string_timestamp(Time.utc(2007, 8, 9), "20070809")
+ assert_convert_from_string_timestamp(Time.utc(2007, 8, 9, 10), "2007080910")
+ assert_convert_from_string_timestamp(Time.utc(2007, 8, 9, 10, 11), "200708091011")
+ assert_convert_from_string_timestamp(Time.utc(2007, 8, 9, 10, 11, 12), "20070809101112")
+ assert_raise(ArgumentError) do
+ TimestampsAsString.convert_from_string_timestamp("2007080910111213")
+ end
+ assert_convert_from_string_timestamp(nil, nil)
+ end
+end