formatted_date 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +3 -0
- data/LICENSE +20 -0
- data/README.rdoc +96 -0
- data/init.rb +1 -0
- data/lib/formatted_date.rb +4 -0
- data/lib/formatted_date/conversion.rb +57 -0
- data/lib/formatted_date/conversion_plugin.rb +80 -0
- data/lib/formatted_date/formatting.rb +78 -0
- data/rails/init.rb +1 -0
- metadata +64 -0
data/CHANGELOG.rdoc
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Ícaro Leopoldino da Motta
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
= FormattedDate
|
2
|
+
|
3
|
+
Esse plugin foi escrito para dar conta da falta de customiza��o do Rails em
|
4
|
+
rela��o a datas em formul�rios.
|
5
|
+
|
6
|
+
O comportamento padr�o do Rails ao se atribuir um dado valor para um atributo de
|
7
|
+
data � mantido. O que muda � que agora s�o realizadas duas convers�es. A
|
8
|
+
primeira � feita pelo plugin e tenta converter o valor passado para uma data de
|
9
|
+
acordo com o formato definido (padr�o brasileiro). Depois essa data � passada
|
10
|
+
ao Rails no formato que ele gosta (padr�o americano).
|
11
|
+
|
12
|
+
FormattedDate tamb�m oferece valida��o inteligente automaticamente. O padr�o �
|
13
|
+
n�o aceitar datas inv�lidas (datas em branco ou <tt>nil</tt> n�o s�o
|
14
|
+
consideradas inv�lidas). Para capturar esses erros existe o famoso
|
15
|
+
<tt>validates_presence_of</tt>.
|
16
|
+
|
17
|
+
----
|
18
|
+
|
19
|
+
=== Configura��o
|
20
|
+
|
21
|
+
No arquivo <i>config/environment.rb</i> adicione o seguinte:
|
22
|
+
|
23
|
+
config.gem 'formatted_date', :source => 'http://gemcutter.org'
|
24
|
+
|
25
|
+
E ent�o execute a task:
|
26
|
+
|
27
|
+
rake gems:install
|
28
|
+
|
29
|
+
----
|
30
|
+
|
31
|
+
=== Exemplos
|
32
|
+
|
33
|
+
No seu modelo chame o m�todo <tt>formatted_date</tt> e passe o nome dos
|
34
|
+
atributos e suas op��es.
|
35
|
+
|
36
|
+
formatted_date :created_at, :publicacao
|
37
|
+
|
38
|
+
O formato padr�o assumido � o brasileiro (dd/mm/YYYY). Mas voc� pode querer um
|
39
|
+
formul�rio com datas em outro formato, por exemplo.
|
40
|
+
|
41
|
+
formatted_date :publicacao, :format => '%d/%m/%Y - %Hh %Mmin'
|
42
|
+
|
43
|
+
Evidentemente voc� pode chamar o m�todo m�ltiplas vezes caso queira passar
|
44
|
+
op��es diferentes para cada atributo.
|
45
|
+
|
46
|
+
formatted_date :date, :validate => false
|
47
|
+
formatted_date :publicacao, :default => Time.current, :message => :invalid
|
48
|
+
|
49
|
+
No exemplo acima voc� viu que existem outras op��es, as quais est�o listadas
|
50
|
+
abaixo.
|
51
|
+
|
52
|
+
<tt>format</tt>::
|
53
|
+
Aceita qualquer formato que o m�todo <tt>strftime</tt> suporte.
|
54
|
+
<tt>default</tt>::
|
55
|
+
O padr�o � <tt>nil</tt>, mas qualquer valor pode ser passado.
|
56
|
+
<tt>validate</tt>::
|
57
|
+
Valor booleano para dizer se o plugin deve adicionar uma mensagem de erro caso
|
58
|
+
a data n�o seja v�lida. Padr�o <tt>true</tt>.
|
59
|
+
<tt>message</tt>::
|
60
|
+
Mensagem a ser exibida caso ocorra algum erro na convers�o para uma data.
|
61
|
+
O padr�o � uma mensagem do tipo <tt>invalid</tt> definida no seu arquivo de
|
62
|
+
localiza��o.
|
63
|
+
<tt>type</tt>::
|
64
|
+
Caso o atributo seja do tipo <i>date</i> voc� deve avisar o plugin passando
|
65
|
+
o s�mbolo <tt>:date</tt> ou a constante <tt>Date</tt>.
|
66
|
+
<tt>range</tt>::
|
67
|
+
Intervalo v�lido para a(s) data(s). Deve ser do tipo <tt>Range</tt>.
|
68
|
+
Padr�o: 1850 � 2038.
|
69
|
+
|
70
|
+
----
|
71
|
+
|
72
|
+
=== M�dulo de Convers�o
|
73
|
+
|
74
|
+
Voc� n�o est� limitado a utilizar esse plugin somente para formatar datas
|
75
|
+
corretamente em formul�rios. Ele vem com um m�dulo para convers�es -
|
76
|
+
<tt>FormattedDate::Conversion</tt>. Utilize-o caso queira converter datas
|
77
|
+
arbitr�rias (n�o s�o atributos de modelos).
|
78
|
+
|
79
|
+
Voc� tem acesso � dois m�todos para convers�o. Ambos tem o mesmo comportamento
|
80
|
+
e aceitam as mesmas op��es do plugin, exceto as op��es de valida��o
|
81
|
+
(<i>message</i> e <i>validate</i>).
|
82
|
+
|
83
|
+
* to_datetime
|
84
|
+
FormattedDate::Conversion.to_datetime('26/11/1986')
|
85
|
+
# => Qua, 26 Nov 1986 00:00:00 +0000
|
86
|
+
* to_date
|
87
|
+
FormattedDate::Conversion.to_date('26/11/1986')
|
88
|
+
# => Wed, 26 Nov 1986
|
89
|
+
|
90
|
+
Uma funcionalidade diferente desses m�todos � que eles retornam um
|
91
|
+
<tt>Array</tt> caso voc� passe mais de uma data. Por exemplo:
|
92
|
+
|
93
|
+
inicio, fim = FormattedDate::Conversion.to_datetime(params[:inicio], params[:fim])
|
94
|
+
|
95
|
+
|
96
|
+
Copyright (c) 2009 �caro Leopoldino da Motta, released under the MIT license
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'formatted_date'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module FormattedDate
|
2
|
+
|
3
|
+
module Conversion
|
4
|
+
|
5
|
+
DefaultOptions = FormattedDate::DefaultOptions.tap { |opts| opts.delete(:message); opts.delete(:validate) }
|
6
|
+
|
7
|
+
#
|
8
|
+
# Tenta fazer a convers�o de cada uma das datas. Em caso de erro,
|
9
|
+
# o valor da op��o <tt>default</tt> � retornado.
|
10
|
+
# O retorno final � um array (se mais de uma data foi passada) com
|
11
|
+
# as datas convertidas (tipo date) de acordo com o formato
|
12
|
+
# especificado pela op��o <tt>format</tt>.
|
13
|
+
#
|
14
|
+
# Exemplos:
|
15
|
+
# hoje = FormattedDate::Conversion.to_date('08/06/2009', :default => Date.today)
|
16
|
+
# inicio, fim = FormattedDate::Conversion.to_date('6-6-6', '12-12-12', :format => '%d-%m-%y')
|
17
|
+
#
|
18
|
+
def self.to_date(*args)
|
19
|
+
convert *args.push(Date)
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Idem ao m�todo date, s� que a convers�o � para um <tt>datetime</tt>.
|
24
|
+
#
|
25
|
+
def self.to_datetime(*args)
|
26
|
+
convert *args.push(DateTime)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def self.convert(*args)
|
32
|
+
klass = args.pop
|
33
|
+
options = args.extract_options!.reverse_merge(DefaultOptions)
|
34
|
+
|
35
|
+
dates = args.map do |date|
|
36
|
+
if date.is_a? String
|
37
|
+
if date.blank?
|
38
|
+
options[:default]
|
39
|
+
else
|
40
|
+
begin
|
41
|
+
parsed = klass.strptime(date, options[:format])
|
42
|
+
options[:range].include?(parsed.year) ? parsed : options[:default]
|
43
|
+
rescue ArgumentError
|
44
|
+
options[:default]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
elsif date.is_a?(Time) || date.is_a?(Date)
|
48
|
+
date
|
49
|
+
else
|
50
|
+
options[:default]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
dates.many? ? dates : dates.first
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module FormattedDate
|
4
|
+
|
5
|
+
class ConversionPlugin #:nodoc:
|
6
|
+
|
7
|
+
VALID = 0
|
8
|
+
INVALID = 1
|
9
|
+
PARSE_FAIL = 2
|
10
|
+
OUT_OF_RANGE = 3
|
11
|
+
|
12
|
+
def initialize(input, options = {})
|
13
|
+
@input = input
|
14
|
+
@output = nil
|
15
|
+
@options = OpenStruct.new(options)
|
16
|
+
@status = INVALID
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Possible conversion methods: <tt>to_date</tt> and <tt>to_datetime</tt>.
|
21
|
+
#
|
22
|
+
def convert!
|
23
|
+
send @options.conversion_method
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid?
|
27
|
+
@status == VALID
|
28
|
+
end
|
29
|
+
|
30
|
+
def invalid?
|
31
|
+
!valid?
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# This is a way to to know if the conversion failed because of a bad input.
|
36
|
+
#
|
37
|
+
def failed_to_parse?
|
38
|
+
@status == PARSE_FAIL
|
39
|
+
end
|
40
|
+
|
41
|
+
def out_of_range?
|
42
|
+
@status == OUT_OF_RANGE
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def perform_conversion(klass)
|
48
|
+
@status, @output = if @input.is_a? String
|
49
|
+
if @input.blank?
|
50
|
+
[INVALID, @options.default]
|
51
|
+
else
|
52
|
+
begin
|
53
|
+
parsed = klass.strptime(@input, @options.format)
|
54
|
+
if @options.range.include? parsed.year
|
55
|
+
[VALID, parsed]
|
56
|
+
else
|
57
|
+
[OUT_OF_RANGE, @options.default]
|
58
|
+
end
|
59
|
+
rescue ArgumentError
|
60
|
+
[PARSE_FAIL, @options.default]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
elsif @input.is_a?(Time) || @input.is_a?(Date)
|
64
|
+
[VALID, @input]
|
65
|
+
else
|
66
|
+
[INVALID, @options.default]
|
67
|
+
end
|
68
|
+
|
69
|
+
@output
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_date
|
73
|
+
perform_conversion Date
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_datetime
|
77
|
+
perform_conversion DateTime
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module FormattedDate
|
2
|
+
|
3
|
+
DefaultOptions = {
|
4
|
+
:format => '%d/%m/%Y',
|
5
|
+
:default => nil,
|
6
|
+
:validate => true,
|
7
|
+
:range => 1850..2038,
|
8
|
+
:message => :invalid,
|
9
|
+
:type => :datetime
|
10
|
+
}
|
11
|
+
|
12
|
+
#
|
13
|
+
# Formata as datas de acordo com o formato passado.
|
14
|
+
#
|
15
|
+
# Leia o <i>README</i> para mais informa��es.
|
16
|
+
#
|
17
|
+
def formatted_date(*args)
|
18
|
+
options = args.extract_options!.reverse_merge(DefaultOptions)
|
19
|
+
|
20
|
+
message = options[:message] || :invalid
|
21
|
+
type = options[:type] || :datetime
|
22
|
+
|
23
|
+
if type.to_s.downcase == 'date'
|
24
|
+
options[:conversion_method] = :to_date
|
25
|
+
options[:db_format] = '%Y-%m-%d'
|
26
|
+
else
|
27
|
+
options[:conversion_method] = :to_datetime
|
28
|
+
options[:db_format] = '%Y-%m-%d %H:%M:%S'
|
29
|
+
end
|
30
|
+
|
31
|
+
args.map(&:to_s).each do |name|
|
32
|
+
|
33
|
+
#
|
34
|
+
# Este � o m�todo que o Rails chama quando est� colocando datas em
|
35
|
+
# campos de formul�rio.
|
36
|
+
# Ele est� sendo sobrescrito para que retorne uma data no formato dado
|
37
|
+
# pela op��o <format>.
|
38
|
+
#
|
39
|
+
define_method "#{name}_before_type_cast" do
|
40
|
+
if self[name].is_a?(Time) || self[name].is_a?(Date)
|
41
|
+
self[name].strftime(options[:format])
|
42
|
+
else
|
43
|
+
self.read_attribute_before_type_cast(name)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# M�todo de atribui��o.
|
49
|
+
#
|
50
|
+
define_method "#{name}=" do |value|
|
51
|
+
conv = ConversionPlugin.new(value, options)
|
52
|
+
date = conv.convert!
|
53
|
+
if conv.valid?
|
54
|
+
self[name] = date.strftime(options[:db_format])
|
55
|
+
else # data inv�lida
|
56
|
+
# O Rails automaticamente tentar� converter esta data, mas n�s
|
57
|
+
# sabemos que ela � inv�lida. De qualquer forma � necess�rio porque
|
58
|
+
# depois n�s devemos ser capazes de resgatar a data sem o cast
|
59
|
+
# (valor de entrada original).
|
60
|
+
self[name] = value
|
61
|
+
|
62
|
+
if options[:validate]
|
63
|
+
self.class.class_eval do
|
64
|
+
validate do |record|
|
65
|
+
if conv.failed_to_parse?
|
66
|
+
# Limpa os erros relacionados a este atributo e adiciona
|
67
|
+
# um outro (padr�o <invalid>).
|
68
|
+
record.errors.instance_eval { @errors.delete(name) }
|
69
|
+
record.errors.add(name, message)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end # end define_method
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'formatted_date'
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: formatted_date
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "\xC3\x8Dcaro Leopoldino da Motta"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-10 00:00:00 -02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Customize o formato de datas no Rails.
|
17
|
+
email: icaro.ldm@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- CHANGELOG.rdoc
|
25
|
+
files:
|
26
|
+
- init.rb
|
27
|
+
- README.rdoc
|
28
|
+
- CHANGELOG.rdoc
|
29
|
+
- LICENSE
|
30
|
+
- rails/init.rb
|
31
|
+
- lib/formatted_date/conversion.rb
|
32
|
+
- lib/formatted_date/conversion_plugin.rb
|
33
|
+
- lib/formatted_date/formatting.rb
|
34
|
+
- lib/formatted_date.rb
|
35
|
+
has_rdoc: true
|
36
|
+
homepage:
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.3.5
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: Customize o formato de datas no Rails.
|
63
|
+
test_files: []
|
64
|
+
|