Get the current date/time in Ruby as string without delimiters? - ruby

Is there any good way to get the current date/time in Ruby as a string without separators, not having to use Time.now.strftime('%Y%m%d'), etc.?
The output I'm looking for is something like "20151002112001" or similar, with all digits and no separators, human-readable form, not Unix time.

I found out that by using Active Support, this can be easily done:
require 'active_support/core_ext/time/conversions'
Time.now.to_formatted_s(:number) # => "20151002112419"
Since I already depend on Active Support, this turned out to be the quickest and easiest way to get this done by far.

You can use .to_i on a Time object to get a number representing Unix-time.
You can convert Date or DateTime objects to Time with .to_time. For example:
string = "#{Date.today.to_time.to_i}"
# "1443769200"
If you need to get certain attributes but don't like strftime, you can use methods of Date. For example, you might do something like
date = Date.today
string = "#{date.year}-#{date.month}-#{date.day}"
# "2015-10-2"
This all works without Active Support, but you still need to require 'date'.

Related

Figure date format from string in ruby

I am working in a simple data loader for text files and would like to add a feature for correctly loading dates into the tables. The problem I have is that I do not know the date format before hand, and it will not be my script doing the inserts - it has to generate insert statements for later use.
The Date.parse is almost what I'd need. If there was a way to grab the format it identified on the string in a way I could use to generate a to_date(...)(Oracle standard) would be perfect.
An example:
My input file:
user_name;birth_date
Sue;20130427
Amy;31/4/1984
Should generate:
insert into my_table values ('Sue', to_date('20130427','yyyymmdd'));
insert into my_table values ('Amy', to_date('31/4/1984','dd/mm/yyyy'));
Note that it is important the original string remains unchanged - so I cannot parse it to a standard format used in the inserts (it is a requirement).
At the moment I am just testing a bunch of regexes and doing some validation, but I was wondering if there was a more robust way.
Suppose (using for example String#scan), you extracted an array of the date strings from a single file. It may be like:
strings = ["20130427", "20130102", ...]
Prepare in advance an array of all formats you can think of. It may be like:
Formats = ["%Y%m%d", "%y%m%d", "%y/%m/%d", "%m/%d/%y", "%d/%m/%y", ...]
Then check all formats that can parse all of the strings:
require "date"
formats =
Formats.select{|format| strings.all?{|s| Date.strptime(s, format) rescue nil}}
If this array formats includes exactly one element, then that means the strings were unambiguously parsed with that format. Using that format, you can go back to the strings and parse them with that format.
Otherwise, either you failed to provide the appropriate format within Formats, or the strings remained ambiguous.
I would use the Chronic gem. It will extract dates in most formats.
It has options to resolve the ambiguity in the xx/xx/xxxx format, but you'd have to specify which to prefer when either match.

How do you check for a changing value within a string

I am doing some localization testing and I have to test for strings in both English and Japaneses. The English string might be 'Waiting time is {0} minutes.' while the Japanese string might be '待ち時間は{0}分です。' where {0} is a number that can change over the course of a test. Both of these strings are coming from there respective property files. How would I be able to check for the presence of the string as well as the number that can change depending on the test that's running.
I should have added the fact that I'm checking these strings on a web page which will display in the relevant language depending on the location of where they are been viewed. And I'm using watir to verify the text.
You can read elsewhere about various theories of the best way to do testing for proper language conversion.
One typical approach is to replace all hard-coded text matches in your code with constants, and then have a file that sets the constants which can be updated based on the language in use. (I've seen that done by wrapping the require of that file in a case statement based on the language being tested. Another approach is an array or hash for each value, enumerated by a variable with a name like 'language', which lets the tests change the language on the fly. So validations would look something like this
b.div(:id => "wait-time-message).text.should == WAIT_TIME_MESSAGE[language]
To match text where part is expected to change but fall within a predictable pattern, use a regular expression. I'd recommend a little reading about regular expressions in ruby, especially using unicode regular expressions in ruby, as well as some experimenting with a tool like Rubular to test regexes
In the case above a regex such as:
/Waiting time is \d+ minutes./ or /待ち時間は\d+分です。/
would match the messages above and expect one or more digits in the middle (note that it would fail if no digits appear, if you want zero or more digits, then you would need a * in place of the +
Don't check for the literal string. Check for some kind of intermediate form that can be used to render the final string.
Sometimes this is done by specifying a message and any placeholder data, like:
[ :waiting_time_in_minutes, 10 ]
Where that would render out as the appropriate localized text.
An alternative is to treat one of the languages as a template, something that's more limited in flexibility but works most of the time. In that case you could use the English version as the string that's returned and use a helper to render it to the final page.

String parse using regex

I have a string which is a function call. I want to parse it and obtain the parameters:
"add_location('http://abc.com/page/1/','This is the title, it is long',39.677765,-45.4343,34454,'http://abc.com/images/image_1.jpg')"
It has a total of 6 parameters and is a mixture of urls, integers and decimals. I can't figure out the regex for the split method which I will be using. Please help!
This is what I have come up with - which is wrong.
/('(.*\/[0-9]*)',)|([0-9]*,)/
Treating the string like a CSV might work:
require 'csv'
str = "add_location('http://abc.com/page/1/','This is the title, it is long',39.677765,-45.4343,34454,'http://abc.com/images/image_1.jpg')"
p CSV.parse(str[13..-2], :quote_char => "'").first
# => ["http://abc.com/page/1/", "This is the title, it is long", "39.677765", "-45.4343", "34454", "http://abc.com/images/image_1.jpg"]
Assuming all non-numeric parameters are enclosed in single quotes, as in your example
string.scan( /'.+?'|[-0-9.]+/ )
You really don't want to be parsing things this complex with a reg-ex; it just won't work in the long run. I'm not sure if you just want to parse this one string, or if there are lots of strings in this form which vary in exact contents. If you give a bit more info about your end goal, you might be able to get some more detailed help.
For parsing things this complex in the general case, you really want to perform proper tokenization (i.e. lexical analysis) of the string. In the past with Ruby, I've had good experiences doing this with Citrus. It's a nice gem for parsing complex tokens/languages like you're trying to do. You can find more about it here:
https://github.com/mjijackson/citrus

Replacing manually written date with a string containing it

I have these 2 things I am working with:
CSV.foreach('datafile.csv','r') {|row| D_Location << row[0]}
puts Date.new(2003,05,02).cwday
In the first line I would like to change the datafile.csv to something like a string so I can change one string and it changes for all of these codes. I have many, each controlling 1 csv column.
In the second one I would like to replace the actual date written, and replace it with a string. This is so that can be automatic, because the string will be generated based on other criteria.
I trust the mods will ban me if I'm being too much of a noob hehe. Then I'll toughen up and find these answers myself eventually. But so far I've solved a lot, but not this. Thanks in advance!
Make a function which takes in a string representing a weekday, and returns a number. Call this function later in your code:
Date.new(2003, 05, yourfun('Tuesday')).cwday
For the first part of your question, you're already working with a string. I think what you mean is that you want it to be in a variable:
csv_file = 'datafile.csv'
CSV.foreach(csv_file,'r') {|row| D_Location << row[0]}
For the second part of your question, Date.parse() works with strings, but they need to be in a format that it can recognize. If your date strings use commas, you can replace them with hyphens:
date_str = "2003,05,02"
Date.parse(date_str.gsub(",", "-")).cwday # => 5
It's not clear where your date strings will be coming from or what format they'll be in, but the general concepts you need to understand are that you can use variables, and that you can transform strings.

Rails url constraint

Im making a url pass in this date format at the very end of the string
2011-11-02T13:59:26.13Z
I can do this
a.sub!(/\..*/,'')
to knock off the .(digit)(digit)Z and work with the time in my controller.
if i put the time in regular format in my url, it works fine. If i put in the specified format above, i get a blank page. If i add the constraint i made (works fine with chopping the end off in the console, I get an routing (no route matches [GET] ...). What should I do to allow to pass in the date format i need (Im using rails 3 if thats important)
The colon is a reseved character and cannot be used within a URL. See RFC 2366 section 2.2
Also, the . (dot) is used to designate a format type in rails, so when this is passed into the router it will try to render a layout for the '13Z' format.
You should encode that time in another format that does not require these characters.
E.g.
20111102135926
Because each field is fixed width it is still easy to parse with a regex.
You could also atime which can be parsed directly in Ruby.

Resources