How do you format moment() to Rails datetime?
Im using react-datepicker and Rails 5 as the back end.
React:
let newDate = this.state.startDate.format('YYYY-MM-DD HH:mm')
console.log(newDate); #=> 2016-10-11 08:46
Looking at the momentjs formats, I see nothing close to rails datetime format ie: Mon, 10 Oct 2016 15:16:29 UTC +00:00
The aim is to pass newDate as params to a rails controller: params[:new_date]
Update:
cema-sp's answer was the final part to my answer but I was getting errors. To solved this:
# JS:
let newDate = this.state.startDate.format(); # no format type
# Controller:
DateTime.strptime(params[:new_date], '%Y-%m-%dT%H:%M:%S%z')
moment.js object newDate may be formatted in any string you like (for example like in the question YYYY-MM-DD HH:mm or default format) and sent to the server:
const newDate = this.state.startDate.format()
...
fetch(apiEndpointUrl, {
method: 'POST',
body: JSON.stringify({
new_date: newDate,
})
}).then(...)
...
The only thing is that you have to parse params[:new_date] on the Rails backend.
Use simple DateTime class parse method or more performant strptime (provide it choosen format).
If you want to update model you may use setter method:
def new_date=(value)
parsed = if value.is_a? String
DateTime.parse(value)
# Or more performant
# DateTime.strptime(value, '%Y-%m-%dT%H:%M:%S%z')
else
value
end
write_attribute(:new_date, parsed)
end
If you need to work with the date in controller, just parse it with one of DateTime methods:
new_date = DateTime.parse(params[:new_date])
# Or
new_date = DateTime.strptime(params[:new_date], '%Y-%m-%dT%H:%M:%S%z')
Related
I have a problem parsing dates taken in from scraping a website using Nokogiri. I scrape the datetime using
#date = h4.at('time[itemprop="startDate"]')[:datetime]
This gives me 2015-04-28 19:30:00 UTC, which is inserted into my date column, of type "datetime".
Using strptime I am trying to parse the date into a "dd/mm" format, and enter it into my Rails table:
Date.strptime(#date, "%Y-%m-%d %H:%M:%S %Z").strftime("%m/%d/%Y")
#event=Event.new
#event.date= #date
Any help would be very much appreciated.
Here's some code that might help:
require 'date'
require 'time'
date = Date.strptime('2015-04-28 19:30:00 UTC', "%Y-%m-%d %H:%M:%S %Z")
# => #<Date: 2015-04-28 ((2457141j,0s,0n),+0s,2299161j)>
date.strftime('%m/%d/%y')
# => "04/28/15"
Parsing into a Date object stores only the year, month and day information.
datetime = DateTime.strptime('2015-04-28 19:30:00 UTC', "%Y-%m-%d %H:%M:%S %Z")
# => #<DateTime: 2015-04-28T19:30:00+00:00 ((2457141j,70200s,0n),+0s,2299161j)>
datetime.strftime('%m/%d/%y')
# => "04/28/15"
time = Time.strptime('2015-04-28 19:30:00 UTC', "%Y-%m-%d %H:%M:%S %Z")
# => 2015-04-28 19:30:00 UTC
time.strftime('%m/%d/%y')
# => "04/28/15"
Parsing into a DateTime, or Time object captures all the information.
The error you're seeing is often caused by a date string in a format you don't expect. That often happens when you expect a value in 'mm/dd/yy' order, but actually receive one in 'dd/mm/yy' order. This happens because the US uses 'mm/dd/yy' and most of the rest of the world uses 'dd/mm/yy':
date = Date.strptime('2015-28-04', '%Y-%m-%d')
# ~> -:7:in `strptime': invalid date (ArgumentError)
or
date = Date.strptime('28-04-2015', '%m-%d-%Y')
# ~> -:7:in `strptime': invalid date (ArgumentError)
You can work around that by using some rescue statements to try several different formats.
You don't want to use parse because it'll assume 'dd/mm/yyyy' and will blow up with US dates, and is slower because it tries multiple formats before giving up. So, using fixed formats you expect is the way to go but you need to search for your various formats of date/datetime strings you'll expect to find and write format strings to match. And, since you're scraping pages, it's possible to find a LOT of bad/malformed values so program defensively.
You don't need strftime and you can parse the date with parse. Just convert the string to a Date object and assign that to your ActiveRecord attribute:
#event = Event.new
#event.date = Date.parse('2015-04-28 19:30:00 UTC')
I have a string ruby something like this.
mystring = "some string value with a date 02/02/2002"
and I would like to extract just the date in order to store it in a database. I am pretty sure I'm going to need some sort of regex and way of searching for the pattern and grabbing it from the string.
Not real sure what needs to be done here.
I found this Regex online that is supposed to allow you to match that date formate.
reg = Regexp.new("^\d{1,2}\/\d{1,2}\/\d{4}$")
How would I go about using that to parse out the above date from the string ?
Kinda cool:
1.9.2-p290 :005 > "some string value with a date 02/02/2002".to_date
=> Sat, 02 Feb 2002
1.9.2-p290 :013 > "some another string 05/07/2012 with stuff after".to_date
=> Thu, 05 Jul 2012
And then do with it anything you want since its class is Date.
(I know it's not regex, but I still think it's cool ;P)
How about this?
s = "some string value with a date 02/02/2002"
regex = /\d{1,2}\/\d{1,2}\/\d{4}/
s[regex] # => "02/02/2002"
Note that you don't need the ^ and $ in your regex as you won't be matching the string in its entirety.
You can try https://rubygems.org/gems/dates_from_string:
text = "1988-1990 and 2000 and one more date 28.04.2015"
dates_from_string = DatesFromString.new()
dates_from_string.get_structure(text)
#=> returns
# [{:type=>:year, :value=>"1988", :distance=>0, :key_words=>[]},
# {:type=>:year, :value=>"1990", :distance=>2, :key_words=>[]},
# {:type=>:year, :value=>"2000", :distance=>5, :key_words=>[]},
# {:type=>:year, :value=>"2015", :distance=>0, :key_words=>[]},
# {:type=>:month, :value=>"04", :distance=>0, :key_words=>[]},
# {:type=>:day, :value=>"28", :distance=>0, :key_words=>[]}]
How do I get DateTime to parse a custom date format(i.e. 'x-%Y')?
I've set the format within an initializer with (as per the RoR API):
Time::DATE_FORMATS[:x_year] = 'x-%Y'
Date::DATE_FORMATS[:x_year] = 'x-%Y'
and when I call:
DateTime.strptime('x-2011', 'x-%Y')
The correct result is returned, but
DateTime.parse('x-2011')
Throws an
ArgumentError: invalid date
never heard of such a possibility. However, you could still do something like:
class DateTime
class << self
alias orig_parse parse
end
def self.parse(string, format = nil)
return DateTime.orig_parse(string) unless format
DateTime.strptime(string, Date::DATE_FORMATS[format])
end
end
in your example it might look like that:
Date::DATE_FORMATS.merge!({:xform => "x-%Y"})
DateTime.parse('x-2011', :xform) #=> Sat, 01 Jan 2011 00:00:00 +0000
You could get rid of 'format' attribute and iterate && validate/rescue through DATE_FORMATS instead
I'm working on a rails project for an Australian website. As a result, they want to be able to enter date formats in the more european-standard of 'dd/mm/yyyy' rather than the US-centric 'mm/dd/yyyy'. I have an ActiveRecord model with a Date field. I'm using jQuery's datepicker to provide the date select on a text field, and have it setting the date to a proper format. But, when I try to save the record, it gets the date wrong. Even when I've set the custom date formats in an intializer according to the i18n guide.
>> b = BlogPost.new
>> b.posted_on = '20/07/2010'
=> "20/07/2010"
>> b.posted_on
=> nil
>> b.posted_on = '07/20/2010'
=> Tue, 20 Jul 2010
It seems that Rails is just using Date.parse to convert the string into a Date object. Is there any way to fix this for the whole project? I don't want to have to write custom code for each model.
class Date
class << self
def _parse_with_us_format(date, *args)
if date =~ %r{^(\d+)/(\d+)/(\d+)$}
_parse_without_us_format("#{$3.length == 2 ? "20#{$3}" : $3}-#{$1}-#{$2}", *args)
else
_parse_without_us_format(date, *args)
end
end
alias_method_chain :_parse, :us_format
end
end
Try to change the default date format (in config/environment.rb)
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.
merge!(default => '%d/%m/%Y %H:%M')
Find out more here http://blog.nominet.org.uk/tech/2007/06/14/date-and-time-formating-issues-in-ruby-on-rails/
I am trying to convert the twitter post dates into datetime objects but for some reason they are not converting correctly. If I do this:
d = '12:06 AM Oct 15th'
and
d = DateTime.parse(d)
or
Tweet.new :body => "test", :created_at => d
then the date ends up Sun Nov 15 00:06:00 -0500 2009. All dates are converting and containing the month of November. Am I totally missing something?
DateTime.parse expects the passed in string to be in a standard format. Since that is not the case with your strings, you'll have to use DateTime.strptime and pass it your string representation of date/time, along with the corresponding format string. In your case something like this should work:
d = DateTime.strptime '12:06 AM Oct 15th', '%H:%M %p %b %d'
d.to_s # => "2009-10-15T00:06:00+00:00"
You can check the documentation to see what each of the formatting directions means.
Always always always use the Chronic gem. Will solve all your problems when it comes to date/time parsing: http://github.com/mojombo/chronic
You might be able to get away with mangling it slightly and then using the parser:
s = '12:06 AM Oct 15th'
d = DateTime.parse(s.sub(/(\w\w\w) /, '\1'))
puts d.to_s
# => 2009-10-15T00:06:00+00:00