I'm using the time_diff gem in a Rails 4 application. I want to show how many days/hours/minutes/seconds are left between the created_at field and created_at + 7.days.
Time.diff(#auction.created_at + 7.days, #auction.created_at, '%d %H %N %S')[:diff]
Output:
7 days 0 hours 0 minutes 0 seconds
How can I get a result like:
7d 0h 0m 0s
Any suggestions?
As per their documentation, you can use %h %m %s instead of %H %N %S
documentation extract:
%h - hour (without adding 'hour' text to the hours. eg: 3 for 3 hours)
%m - minute (without adding 'minute' text)
%s - second (without adding 'second' text)
So your code should be
Time.diff(#auction.created_at + 7.days, #auction.created_at, '%d %hh %mm %ss')[:diff]
Now for the day you need to use a i18n yaml file
en:
day: "d"
Related
anyone can help me?
I have a string with format: 10 mins - 20 mins OR 1 min - 10 mins OR 10 mins - 1 hour OR 10 mins - 1 hour 30 mins OR 10 mins - 2 hours OR 10 mins - 2 hours 30 mins.
I wanna create a regex for all formats but I can't :disappointed: . Please help me, thanks a lot.
A regex possible with all above formats.
I might split on the dash first, then match out the components in each side using the same regular expression.
E.g.
"1 hour 10 mins - 3 hours".split(/\s+-\s+/, 2).map do |s|
s.scan(
/
\d+ \s+ mins
| \d+ \s+ hour(?=s?)
| \d+ \s+ hour(?=s?)
\s+
\d+ \s+ min(?=s?)
/x
)
end
# => [["1 hour", "10 mins"], ["3 hour"]]
"1 hour 10 mins - 40 mins".split(/\s+-\s+/, 2).map do |s|
s.scan(
/
\d+ \s+ mins
| \d+ \s+ hour(?=s?)
| \d+ \s+ hour(?=s?)
\s+
\d+ \s+ min(?=s?)
/x
)
end
# [["1 hour", "10 mins"], ["40 mins"]]
I've assumed:
every string contains only minutes (not hours) to the left of the minus sign; and
hours, where present, are between 1 and 9.
These assumptions are consistent with the examples given in the question.
One can then use String#match and MatchData#named_captures with the regular expression
rgx = /(?<lmin>(?:[1-9]|[1-5]\d)) mins? \- (?:(?<hr>[1-9]) hours?(?: (?<rminwhr>\g<lmin>) mins?)?|(?<rminwohr>\g<lmin>) mins?)/
to extract the values of interest. Let's try it for the examples given in the question.
["10 mins - 20 mins",
"1 min - 10 mins",
"10 mins - 1 hour",
"10 mins - 1 hour 30 mins",
"10 mins - 2 hours",
"10 mins - 2 hours 30 mins"].each do |str|
m = str.match(rgx)
puts str
puts "str.match(rgx) = #{m.inspect}"
puts "captures = #{m.named_captures}"
puts
end
displays the following.
10 mins - 20 mins
str.match(rgx) = #<MatchData "10 mins - 20 mins" lmin:"20" hr:nil rminwhr:nil rminwohr:"20">
captures = {"lmin"=>"20", "hr"=>nil, "rminwhr"=>nil, "rminwohr"=>"20"}
1 min - 10 mins
str.match(rgx) = #<MatchData "1 min - 10 mins" lmin:"10" hr:nil rminwhr:nil rminwohr:"10">
captures = {"lmin"=>"10", "hr"=>nil, "rminwhr"=>nil, "rminwohr"=>"10"}
10 mins - 1 hour
str.match(rgx) = #<MatchData "10 mins - 1 hour" lmin:"10" hr:"1" rminwhr:nil rminwohr:nil>
captures = {"lmin"=>"10", "hr"=>"1", "rminwhr"=>nil, "rminwohr"=>nil}
10 mins - 1 hour 30 mins
str.match(rgx) = #<MatchData "10 mins - 1 hour 30 mins" lmin:"30" hr:"1" rminwhr:"30" rminwohr:nil>
captures = {"lmin"=>"30", "hr"=>"1", "rminwhr"=>"30", "rminwohr"=>nil}
10 mins - 2 hours
str.match(rgx) = #<MatchData "10 mins - 2 hours" lmin:"10" hr:"2" rminwhr:nil rminwohr:nil>
captures = {"lmin"=>"10", "hr"=>"2", "rminwhr"=>nil, "rminwohr"=>nil}
10 mins - 2 hours 30 mins
str.match(rgx) = #<MatchData "10 mins - 2 hours 30 mins" lmin:"30" hr:"2" rminwhr:"30" rminwohr:nil>
captures = {"lmin"=>"30", "hr"=>"2", "rminwhr"=>"30", "rminwohr"=>nil}
lmin reads "minutes to left of minus sign"; rminwhr (rminwohr) reads "minutes to right of minus sign with (without) hours".
One can see a demonstration of the regular expression here. Hover the cursor over the regular expression to see an explanation of the function of each part of the expression. These results are shown for the PCRE regex engine but they are the same for Ruby's regex engine (Oniguruma).
We can write the regular expression in free-spacing mode to make it self-documenting.
/
(?<lmin> # begin capture group 'lmin'
(?: # begin non-capture group
[1-9] # match a digit other than zero
| # or
[1-5]\d # match a digit between 1 and 5, followed by a digit
) # end non-capture group
) # end capture group 'lmin'
[ ]mins? # match a space followed by 'min', 's' optional
[ ]\-[ ] # match ' - '
(?: # begin non-capture group
(?<hr> # begin capture group 'hr'
[1-9] # match a digit other than zero
) # end capture group 'hr'
[ ]hours? # match a space followed by 'hour', 's' optional
(?: # begin a non-capture group
[ ] # match a space
(?<rminwhr> # begin capture group 'rminwhr'
\g<lmin> # invoke subexpression 'lmin'
) # end capture group 'rminwhr'
[ ]mins? # match a space followed by 'min', 's' optional
) # end non-capture group
? # make the preceding non-capture group optional
| # or
(?<rminwohr> # begin capture group 'rminwohr'
\g<lmin> # invoke subexpression 'lmin'
) # end capture group 'rminwohr'
[ ]mins? # match a space followed by 'min', 's' optional
) # end non-capture group
/x # invoke free-spacing regex definition mode
g<lmin> causes the code used to create named capture group named lmin to be reused at that location. This is called a "subexpression" or "subrouting". For an explanation search for "Subexpression" in Regexp. The use of subexpressions reduces the size of the expression, makes it easier to read and reduces the chances of errors, particularly if the expression is modified in future.
Notice that in free-spacing mode spaces that are intended to part of the expression must be protected in some way to prevent them from being stripped out before the expression is parsed. I've chosen to put each one in a character class, but there are other ways of doing that (for one, escaping the space character).
I am trying to extract the time from a DateTime example 2022-02-26 10:00:00 UTC I want to return only the 10:00:00 from it. Please help Using Rails v.6
By using strftime method and passing "%H:%M:%S" format to it
%H - Hour of the day, 24-hour clock, zero-padded (00..23)
%k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
%I - Hour of the day, 12-hour clock, zero-padded (01..12)
%M - Minute of the hour (00..59)
%S - Second of the minute (00..59)
%P - Meridian indicator, lowercase (``am'' or ``pm'')
%p - Meridian indicator, uppercase (``AM'' or ``PM'')
date = DateTime.now
date.strftime("%H:%M:%S")
# Output 07:44:10
Or if you need to have all segment separately you can extract hours, minutes and seconds like this:
date = DateTime.now
hour = date.hour # 07
minute = date.minute # 44
second = date.second # 10
# and you can interpolate
time = "#{hour}:#{minute}:#{second}"
I'm scratching my head trying to work with time functions within Cognos 10.2.1 (Report Studio), using an Informix db as a data source.
My time field is stored as a smallint, 4 digits, representing the 24 hour clock. I am trying to get the time to display as 6:00pm, 11:30am, 3:00pm, etc. I have a separate data expression that calculates the string 'AM' or 'PM' depending on the hour value, but I'm running into some errors when doing the overall concat/substring function.
case when char_length([Query1].[beg_tm]) = 4
then (substring(cast([StartTime], char(5)), 1, 2)) || ':' || (substring (cast ([StartTime], char(5)), 3, 2)) || ([beg_AMPMcalc])
when char_length([Query1].[beg_tm]) = 3
then (substring(cast([StartTime], char(5)), 1, 1)) || ':' || (substring(cast ([StartTime], char(5)), 3, 2)) || ([beg_AMPMcalc])
else '--'
end
Why not use DATETIME HOUR TO MINUTE; at least you then only have to deal with converting 24 hour clock to 12 hour clock. Is midnight stored as 0 and noon as 1200, and the minute before midnight as 2359? Cognos uses a fairly modern version of Informix, I believe, so you should be able to use the TO_CHAR function:
DROP TABLE IF EXISTS times;
CREATE TEMP TABLE times(p_time SMALLINT);
INSERT INTO times VALUES(0);
INSERT INTO times VALUES(59);
INSERT INTO times VALUES(100);
INSERT INTO times VALUES(845);
INSERT INTO times VALUES(1159);
INSERT INTO times VALUES(1200);
INSERT INTO times VALUES(1259);
INSERT INTO times VALUES(1300);
INSERT INTO times VALUES(1815);
INSERT INTO times VALUES(2359);
SELECT TO_CHAR(CURRENT HOUR TO MINUTE, "%I:%M %p"),
p_time,
DATETIME(00:00) HOUR TO MINUTE + MOD(p_time, 100) UNITS MINUTE + (p_time/100) UNITS HOUR,
TO_CHAR(DATETIME(00:00) HOUR TO MINUTE + MOD(p_time, 100) UNITS MINUTE + (p_time/100) UNITS HOUR, "%I:%M %p")
FROM times;
Output:
03:49 AM 0 00:00 12:00 AM
03:49 AM 59 00:59 12:59 AM
03:49 AM 100 01:00 01:00 AM
03:49 AM 845 08:45 08:45 AM
03:49 AM 1159 11:59 11:59 AM
03:49 AM 1200 12:00 12:00 PM
03:49 AM 1259 12:59 12:59 PM
03:49 AM 1300 13:00 01:00 PM
03:49 AM 1815 18:15 06:15 PM
03:49 AM 2359 23:59 11:59 PM
I'm using a database server that has its local time set to UTC, and I'm in time zone -07:00 (US/Pacific); the current time isn't the middle of the night where I am.
I have a breeze entity with a date in it, I need to get the year, month, day separately and was going to use momentjs to do it but I'm getting some strange results for something that I would have thought would be quite simple:
var dob = moment(observableDate());
console.log(observableDate() + ' to -> ' + dob.day() + ' - ' + dob.month() + ' - ' + dob.year());
//ouput
//Thu Dec 18 1975 11:00:00 GMT+1100 (AUS Eastern Summer Time) to -> 4 - 11 - 1975
I don't understand where the 4th of Nov is coming from....
The date is stored in Sql Server and the value is '1975-12-18 00:00:00.000'
Thanks in advance.
According to the moment.js documentation
day() returns the day of the week, i.e. a number between 0 and 6; (4 == thursday).
month() returns the month of the year but 0 origin. i.e. a number between 0 and 11 - (11 == december)
See: Moment.js docs
I have a ruby application where i need to get date-time difference in Days-Hours-Minutes format. For this i m using following function
def duration (from_time, to_time)
from_time = from_time.to_time if from_time.respond_to?(:to_time)
to_time = to_time.to_time if to_time.respond_to?(:to_time)
distance_in_seconds = ((to_time - from_time).abs).round
secs = distance_in_seconds.to_int
mins = secs / 60
hours = mins / 60
days = hours / 24
if days > 0
"#{days}d #{hours % 24}h"
elsif hours > 0
"#{hours}h #{mins % 60}m"
elsif mins > 0
"#{mins}m"
end
end
The above called like this from another function
duration(aw_updated, Time.now)
But some time it gives me wrong result,
when i display above values
aw_updated is 2012-09-19 04:23:34 UTC
Time.now is 2012-09-19 16:33:09 +0530
Time.now.utc is 2012-09-19 11:03:09 UTC
And
Diff is 6h 26m
But my system time is 2012-09-19 16:33:09
Not sure where i m doing wrong , some UTC issue?
please advise
For correct answer your both time should have same timezone utc in this case
So it is converting 2012-09-19 16:33:09 +0530 into utc which gives 2012-09-19 11:03:09 UTC and hence difference is Diff is 6h 26m
Would enter this as a comment but can't yet.
I haven't looked in detail at your function but do you have to build it from scratch? Why don't you use the Ruby in built DateTime class. You can parse strings to DateTime objects, do the calculation and use the strftime method to output the time in a format that you want