In Ruby, compare two strings as dates and get the older one - ruby

Much like this OP asked in Java, I'd like to know how to do in Ruby:
How to compare a date - String in the custom format “dd.MM.yyyy, HH:mm:ss” with another one?
I have these two strings, which convey dates and time and I would like to find the older one of the two:
20141024_133641
20141024_142440
The format is %Y%m%d_%H%M%S ; which makes the former the older one in this case.

Plain lexicographical string comparison will do the job here as your date strings are ordered from most significant to least significant (years to seconds) in strict order. If d1 is your first date and d2 is your second date string, then simple ruby will get the older one:
[d1,d2].min

You could use DateTime.parse
d1 = DateTime.parse("20141024_142440","%Y%m%d_%H%M%S")
d2 = DateTime.parse("20141024_133641","%Y%m%d_%H%M%S")
and compare them as usual
if d1 > d2 ...
or like #kroky said
[d1,d2].min.to_s #=> "2014-10-24T13:36:41+00:00"
[d1,d2].max.to_s #=> "2014-10-24T14:24:40+00:00"

Related

What is a simple way in Ruby to show the date and time?

I would like something in Ruby roughly equivalent to time.asctime() in Python:
import time
print(time.asctime())
outputs:
Sun Sep 11 10:12:48 2022
I'd like to avoid having to use strftime and having to remember or look up the formats. Also, ideally I'd like both day of the week (e.g., Sun) and the UTC timezone difference (e.g., -0400), but I'd settle for just day of the week.
puts Time.now.asctime
outputs:
Sun Sep 11 10:24:46 2022
Simple String Output
Ruby supports lots of Time, Date, and DateTime objects and output formats. While I think the first answer is closer to the output format you want, the following is potentially simpler and possibly sufficient for many needs when just considering standard output or standard error:
p Time.now.to_s
#=> 2022-09-11 14:10:57 -0400
# using interpolation
p "Time: #{Time.now.to_s}"
#=> "Time: 2022-09-11 14:15:51 -0400"
Other Considerations
Note that if you want to use the results for any sort of comparison or calculation, you'll likely need to convert the result to one of the three object types described above. That's the main reason I mention them. Unless it's just printing to the screen, you should think about how you plan to use the result before deciding which of the objects will be most useful for you.

Qtp add more than 15 strings or convert more than 15 strings

Can someone please guide me on how to convert more than 6 characters into int? Because I need to do sum after convert to int. I tried so many ways like CInt, CLng, etc still throw exponential value.
Stroutput = 2018050302216556
Sum = Stroutput + 1
I tried to divide into sveral chuck using right function but it doesnt look good. Can be manage but I need another option. Thanks
You seem to be working with a Date Structure, which as VBS says - hard to represent as numbers only. Use the CDate to get a date object from the string (If needed change the representation of that string to (YYYY-mm-dd ...). With the DateAdd method you can add days, years etc; and finally the FormatDateTime will create an output of your wish.

Sorting English Style dates

I have a macro which is sorting a group of columns in an ascending order using column A which has an English format date and time in it. Each selection of data in the sheet covers two days. That's fine and working OK until the month changes at which point 30/04/2014 is treated as a larger value than 01/05/2014. At that point the 01/05/2014 rows are put to the top and the 30/04/2014 are sorted to the bottom, the opposite of what i would want.
Here's the snippet of code that does the sorting.
With Range("AA1")
.Value = 1
.Copy
'Modified the value conversion section to avoid changing the date to an american format
With Range("B1:Z" & WriteToRow - 1)
.PasteSpecial Paste:=xlPasteValues, Operation:=xlMultiply
End With
With Range("A1:Z" & WriteToRow - 1)
.Sort key1:=Range("A2"), order1:=xlAscending, Header:=xlYes
.EntireColumn.AutoFit
End With
.Value = ""
Can anyone help with this? I have thought that i could add an IF statement to say if the first 2 characters of A2 are 01 then sort descending but then i would need another IF to say that if the first two characters are 02 sort again into ascending so that when the file is processing between the 1st and 2nd of each month the order is correct. It seemed a bit messy to me so i thought i'd see if someone much smarter than me had a cleaner solution.
Thanks, 7's
Even though the control panel is set to proper Locale or Language, the developer might be from a completely different location handling projects from different nation.
It is nice to read different views from all experts. To override OS or Excel Intelligence from determining the date format, it is better to format it by using "=Text" command.

Yearless Ruby dates?

Is there a way to represent dates like 12/25 without year information? I'm thinking of just using an array of [month, year] unless there is a better way.
You could use the Date class and hard set the year to a leap year (so that you could represent 2/29 if you wanted). This would be convenient if you needed to perform 'distance' calculations between two dates (assuming that you didn't need to wrap across year boundaries and that you didn't care about the off-by-one day answers you'd get when crossing 2/29 incorrectly for some years).
It might also be convenient because you could use #strftime to display the date as (for example) "Mar-3" if you wanted.
Depending on the usage, though, I think I would probably represent them explicitly, either in a paired array or something like YearlessDate = Struct.new(:month,:day). That way you're not tempted to make mistakes like those mentioned above.
However, I've never had a date that wasn't actually associated with a year. Assuming this is the case for you, then #SeanHill's answer is best: keep the year info but don't display it to the user when it's not appropriate.
You would use the strftime function from the Time class.
time = Time.now
time.strftime("%m/%d")
While #Phrogz answer makes perfect sense, it has a downside:
YearlessDate = Struct.new(:month,:day)
yearless_date = YearlessDate.new(5, 8)
This interface is prone to MM, DD versus DD, MM confusion.
You might want to use Date instead and consider the year 0 as "yearless date" (provided you're not a historian dealing with real dates around bc/ad of course).
The year 0 is a leap year and therefore accommodates every possible day/month duple:
Date.parse("0000-02-29").leap? #=> true
If you want to make this convention air tight, just define your own class around it, here's a minimalistic example:
class YearlessDate < Date
private :year
end
The most "correct" way to represent a date without a year is as a Fixnum between 001 and 365. You can do comparisons on them without having to turn it into a date, and can easily create a date for a given year as needed using Date.ordinal

Generating confirmation numbers

I need a technique (an a pointer to sample code if you have) for generating conformation numbers for web payment. I don't want the customer to write down a long sequence like a GUID but I don't want it easily predictable as well.
Using C#
Thanks for all the tips.
I decided on a format like this:
TdddRROOO
T = 2009 (next year will be U = 2010)
ddd = days this year
RR = two random numbers
000 = order number (I'll offset this so folks can't know the order number that day)
So the confirmation number will be something like
P23477098
You could do something with a mixture. Generate the first half of the key as a known, predictable value (e.g. 00001, 00002, 00003, etc.) and then generate the second half as a randomly generated value so it won't be predictable. Then, increment the "known, predictable" value so that you will never get a match.
Your unique code would then become: 00001-53481, 00002-43853, 00003-54511, etc.
Of course, I am sure there are libraries out there that probably do this already. (It might help if you specify what language you are using.)
I recent did same thing in PHP. We use random function in this class,
https://github.com/kohana/core/blob/3.3/master/classes/Kohana/Text.php
We use random('distinct', 8) to generate confirmation number. It generates strings like this,
4CFY24HJ
JH5AYL7J
2TVWTMJ5
As you can see, it has no confusing numbers/letters like (1/l, 0/O etc) so it makes it much clearer when customers have to read the numbers over the phone.
Decide on the characters (char[] chars) that you want in your confirmation code, decide on the length of confirmation code (n), generate n random numbers (i_1, i_2, ... i_n) in the range [0..chars.Length) and return the string chars[i_1]chars[i_2]...chars[i_n].
In C#:
public string ConfirmationCode(char[] chars, int length, Random rg) {
StringBuilder codeBuilder = new StringBuilder();
for(int i = 0; i < length; i++) {
int index = rg.Next(chars.Length);
codeBuilder.Append(chars[index]);
}
return codeBuilder.ToString();
For uniqueness, prepend the current time in yyyyMMddhhmmss format.
Just generate a random number between 100000 and 999999, for example. Also a good idea is to put some letters in front that identify that it is a confirmation number, such as CONF-843682 so that people will recognize it more easily when you ask for it.
Store the number in the database, together with an ID for the order and an expiry date (say 1 year).
You could do something like get a random number of a specified length, convert to base64 and add a checksum character.
How about something like Amazon's PayPhrase? Use a library like Faker (Ruby) or Data::Faker (Perl) to generate random phrases, or write your own utility. Then just use a simple hash function to convert the "confirmation phrase" into a number you can index.
As for C# there exists a port Ruby's Faker gem at http://github.com/slashdotdash/faker-cs

Resources