At the moment I have:
type: string
format: YYYY-MM-DD
How can I match a date formatted like: Jan 22, 2020?
Is there a predefined way or I have to create a kind of regex?
Is it possible to use pattern instead of format?
I got an idea with regex, even tough is not matching it strictly:
type: string
pattern: '^[a-zA-Z]+ [0-9]+, [0-9]+$'
Related
I need to convert a string that represents a date to a timestamp object in Ruby.
For example:
date_string = "18-Feb-2016 09:01:04"
convert to a timestamp like so
2016-02-18 14:01:04
I need to save this to a mysql database were the column is type timestamp.
I have researched this for most of the day and can not find a solution. I know you can use Time.parse but that includes timezone and DateTime.parse().to_time includes the timezone. Since it has to be a timestamp i can not use strftime method.
I need the time to be included because it will be used for calculation purposes.
Any help would be greatly appreciated.
Thank you
TL;DR
datetime = DateTime.parse("18-Feb-2016 09:01:04").to_s(:db)
returns
"2016-02-18 09:01:04"
Here's a quick explanation...
1. Convert your string to a Date object with DateTime.parse
You can use the .parse method from the Date or DateTime class in order to parse a string. The parse method will return a Date object like this:
$ DateTime.parse("18-Feb-2016 09:01:04")
$ => #<DateTime: 2016-02-18T09:01:04+00:00 ((2457437j,32464s,0n),+0s,2299161j)>
.parse is a method provided by Ruby.
2. Format the string with DateTime.parse.to_s
Ruby on Rails gives you access to the DateTime.to_formatted_s method to change the formatting of the Date object prior to storing it in your database.
To match the format that you specified:
$ datetime = DateTime.parse("18-Feb-2016 09:01:04").to_formatted_s
Note: to_s is aliased from to_formatted_s and to_formatted_s is a method provided by Rails, not Ruby.
Use to_datetime method in Rails.
"12-10-2015".to_datetime
=> Mon, 12 Oct 2015 10:36:00 +0000
http://apidock.com/rails/String/to_datetime
Edited to add precise answer.
You can use .to_time or .to_datetime, the .to_time returns the date and time with timezone but the .to_datetime returns full date with week name but it shows +0000 as timezone, you will see the difference in both the formats, see the following example.
# used .to_time
"18-Feb-2016 09:01:04".to_time
## Output
2016-02-18 09:01:04 +0530
# used .to_datetime
"18-Feb-2016 09:01:04".to_datetime
## Output
Thu, 18 Feb 2016 09:01:04 +0000
I've interpreted the question to be that you wish to convert the string "18-Feb-2016 09:01:04" to the string "2016-02-18 14:01:04" (generalized to arbitrary date-time strings, of course).
Let:
str = "18-Feb-2016 09:01:04"
What you want is done in two steps. The first is to convert this string to a DateTime object, that is, an instance of the class DateTime. The second step is to construct the desired string from the DateTime object.
One way to create the DateTime object is to use the method DateTime::parse:
require 'date'
DateTime.parse(str)
#=> #<DateTime: 2016-02-18T09:01:04+00:00 ((2457437j,32464s,0n),+0s,2299161j)>
That works fine for the string format you gave, but can be problematic with other formats. For example:
DateTime.parse "4-5-16 09:01:04"
#=> #<DateTime: 2004-05-16T09:01:04+00:00 ((2453142j,32464s,0n),+0s,2299161j)>
As long as you know the format that will be used, it's generally better to use DateTime#strptime with the appropriate pattern comprised of format directives:
pattern = "%d-%m-%y %H:%M:%S"
DateTime.strptime("4-5-16 09:01:04", pattern)
#=> #<DateTime: 2016-05-04T09:01:04+00:00((2457513j,32464s,0n),+0s,2299161j)>
See DateTime#strftime for the format directives.
For the problem at hand:
dt = DateTime.strptime(str, "%d-%b-%Y %H:%M:%S")
#=> #<DateTime: 2016-02-18T09:01:04+00:00 ((2457437j,32464s,0n),+0s,2299161j)>
The second step is to construct the desired string with the above-referenced strftime method:
dt.strftime("%Y-%m-%d %H:%M:%S")
#=> "2016-02-18 09:01:04"
I have some strings that might or might not be dates like:
"Hello World", "Sept 12, 2013", "Hello World Sept 12"
In this case, I'd like only the second one to be considered a proper date.
So far, I have been using Date.parse and the Chronic gem but they very lenient and convert strings like "a a" or "12-UNKN/34/OWN1" into acceptable dates.
For example:
Date.parse '12-UNKN/34/OWN1'
would return:
Tue, 12 Nov 2013
So, I am trying to restrict the accepted formats to a set of formats I can control:
09/12/2013
9/12/2013
9/12/13
09-12-2013
9-12-2013
9-12-13
and some formats with text inside like:
Sept 9, 2013 - with or without the coma, accepting Sep, Sept or September and with or without a dot after the month name, covering things like:
Sept. 9, 2013
Sept 09, 2013
Sept. 09, 2013
September 9, 2013
September 09, 2013
Any suggestion on a good way to do this in Ruby, either pure Ruby or with Rails?
I'll take a stab at this and elaborate on my comment. Separating the date from the other string allows you to validate the date in multiple formats before handing it off to Chronic:
validates_format_of :date, with: /\d{2,4}[-/]\d{1,2}[-/]\d{1,4}/, on: :create
That should handle most of the date formats you described.
However, a big issue is you won't know if someone is submitting a date in the US format or non-US format.
The bigger issue is know what part of the title string is in fact a date, and that would either be a more complicated regular expression, or make it easy on yourself and make it a separate field. You're getting somewhat close to trying to parse natural language which isn't cut and dry by any means.
Try something like this
validate :validate_some_date
private
def validate_some_date
errors.add("Created at date", "is invalid.") unless [
date_case_one,
date_case_two,
date_case_three
].all?
end
def date_case_one
# some regex
end
def date_case_two
# some regex
end
def date_case_three
# some regex
end
I wanted to add the 'th', 'nd' suffix to my date. This question solve a part of the problem : In Ruby on Rails, how do I format a date with the "th" suffix, as in, "Sun Oct 5th"?
But I need to add it in /config/en.yml . How o do it?
You can pass the string to the locale
en:
foo: "it is the %{day} of %{month} today"
I18n.t('foo', day: Date.today.day.ordinalize, month: Date::MONTHNAMES[Date.today.month] )
I have a form input in my application that accepts dates in the format DD/MM/YYYY eg 02/05/2012 is 2nd May 2012.
What is the best way for me to convert this into a suitable format to be added to the database through ActiveRecord?
Is there a simply way of converting 02/05/2012 to 05/02/2012 before adding to the database?
This is similar to Getting rails to accept European date format (dd/mm/yyyy)
In your model, create a setter method, where "my_date" is your database field.
def my_date=(val)
Date.strptime(val, "%d/%m/%Y") if val.present?
end
For this specific format you can call DateTime.parse:
DateTime.parse("02/05/2012") # => Thu, 02 May 2012 00:00:00 +0000
2 Years later but it's something I came across too, here's my fix.
In your view, use:
<%= l article.created_at, format: :euro %> **make sure to add the l
And then in /config/locales/en.yml add:
en:
time:
formats:
euro: "%d/%m/%Y"
** you can also just add, euro: "%D" to display in the us date format.
Thanks.
What is the easiest way to use these variables:
year: "2011"
month: "8"
date: "28"
hours: "1"
minutes: "4"
to create a DateTime (i.e. Sun, 28 Aug 2011 01:04:00 +1000). The time zone does not matter.
Use DateTime::civil
DateTime.civil(year.to_i, month.to_i, date.to_i, hours.to_i, minutes.to_i)
Change that to to_i(10) everywhere if you're worried about something like "08" being interpreted as an octal number.
Use DateTime.civil. Here is more info: civil