Get start and end epoch times for today - ruby

I'm using an API that requires a start_time and an end_time in epoch that will give me data between those times. The question is I want all the data from the start of UTC today to the end of UTC today.
What's the most effective way to do this in ruby?

You can use the ActiveSupport Date functions #beginning_of_day and #end_of_day. And use to_i to convert the time to seconds since Epoch.
require 'active_support/core_ext'
Date.today.beginning_of_day.to_i
# => 1395532800
Date.today.end_of_day.to_i
# => 1395619199

Date.today.to_time.to_i
should get you the start, and
(Date.today + 1).to_time.to_i
should get you the end.

If you are not using rails or do not wish to import require 'active_support/core_ext' for some reason you can do it using ruby as follows
Date.today.to_time.to_i # beginning_of_day
=> 1481221800
Date.today.to_time.change(hour: 23, min: 59, sec: 59).to_i # end_of_day
=> 1481308199

Related

looking for a method that will show tomorrow's date in ruby

Though, I already got the answer to my question, I decided to edit it.
I was looking for any method in Ruby that can show tomorrow's date.
It's ok if it will show the time as well, I will format its output.
The Time.now gives current date, time and timezone:
Time.now
=> 2013-06-11 13:09:02 +0900
How can I use this method to get a date for tomorrow?
It's ok if there are other methods that can do it.
require 'date'
tomorrow = Date.today + 1
tomorrow is a date object. You can print it in the format you want.
Try:
Time.now + 24*60*60
(Edited: xaxxon is right. My earlier version used Rails' functionality)
ruby 2.6+ helper method
Date.tomorrow
Similar to Stu Gla:
today = Time.now
tomorrow = today + (60 * 60 * 24)
you can then use the .strftime method to format... example:
puts tomorrow.strftime("%F")
# => 2014-08-07

Ruby DateTime.Parse to local time

I have a date string 20101129220021, so I will use
require 'date'
d = DateTime.parse('20101129220021')
This part works fine, and I get a date, which is in UTC.
My question is, how can I convert this into my local time? I tried many methods like extracting the time part using d.to_time and manipulate the result, but it didn't work. As far as I know, DateTime object is immutable. Can I please get some help?
irb(main):001:0> require "date"
=> true
irb(main):002:0> d = DateTime.parse('20101129220021')
=> #<DateTime: 2010-11-29T22:00:21+00:00 (70719276007/28800,0/1,2299161)>
irb(main):003:0> d.to_time
=> 2010-11-30 00:00:21 +0200
ruby 1.9.2p180 (2011-02-18)
You can add a rational fraction based on the timezone to get the local time.
require 'date'
# Make this whatever your zone is. Using UTC +0300 here.
ZONE = 3
d = DateTime.parse('20101129220021') + Rational(ZONE,24)
d.to_s # => "2010-11-30T01:00:21+00:00"

Is there a comprehensive library/module for ISO 8601 in ruby?

Is there already an implementation of all the date, time, duration and interval usage of the ISO 8601 standard in ruby? I mean something like a Class where you can set and get the details like, year, month, day, day_of_the_week, week, hour, minutes, is_duration?, has_recurrence? and so on which also can be set by and exported to a string?
require 'time'
time = Time.iso8601 Time.now.iso8601 # iso8601 <--> string
time.year # => Year of the date
time.month # => Month of the date (1 to 12)
time.day # => Day of the date (1 to 31 )
time.wday # => 0: Day of week: 0 is Sunday
time.yday # => 365: Day of year
time.hour # => 23: 24-hour clock
time.min # => 59
time.sec # => 59
time.usec # => 999999: microseconds
time.zone # => "UTC": timezone name
Have a look at the Time. It has a lot of stuff in it.
Unfortunately Ruby's built-in Date-Time functions do not seem to be well thought through (comparing to .NET for example), so for other functionality you will need to use some gems.
Good thing is that using those gems does feel like it's a built-into Ruby implementation.
Most useful probably is Time Calculations from ActiveSupport (Rails 3).
You don't need to require the rails but only this small library: gem install activesupport.
Then you can do:
require 'active_support/all'
Time.now.advance(:hours => 1) - Time.now # ~ 3600
1.hour.from_now - Time.now # ~ 3600 - same as above
Time.now.at_beginning_of_day # ~ 2010-11-24 00:00:00 +1100
# also at_beginning_of_xxx: xx in [day, month, quarter, year, week]
# same applies to at_end_of_xxx
There are really a lot of things that you can do and I believe you will find what suites your needs very well.
So instead of giving you abstract examples here I encourage you to experiment with irb requiring active_support from it.
Keep the Time Calculations at hand.
Ruby Time library adds an iso8601 method to the Time class. See here.
I don't know of a gem that exports the other ISO 8601 formats. You could extend the Time class yourself to add them.
Often you'll use the strftime method to print out specific formats. Example.

get next/previous month from a Time object

I have a Time object and would like to find the next/previous month. Adding subtracting days does not work as the days per month vary.
time = Time.parse('21-12-2008 10:51 UTC')
next_month = time + 31 * 24 * 60 * 60
Incrementing the month also falls down as one would have to take care of the rolling
time = Time.parse('21-12-2008 10:51 UTC')
next_month = Time.utc(time.year, time.month+1)
time = Time.parse('01-12-2008 10:51 UTC')
previous_month = Time.utc(time.year, time.month-1)
The only thing I found working was
time = Time.parse('21-12-2008 10:51 UTC')
d = Date.new(time.year, time.month, time.day)
d >>= 1
next_month = Time.utc(d.year, d.month, d.day, time.hour, time.min, time.sec, time.usec)
Is there a more elegant way of doing this that I am not seeing?
How would you do it?
Ruby on Rails
Note: This only works in Rails (Thanks Steve!) but I'm keeping it here in case others are using Rails and wish to use these more intuitive methods.
Super simple - thank you Ruby on Rails!
Time.now + 1.month
Time.now - 1.month
Or, another option if it's in relation to the current time (Rails 3+ only).
1.month.from_now
1.month.ago
Personally I prefer using:
Time.now.beginning_of_month - 1.day # previous month
Time.now.end_of_month + 1.day # next month
It always works and is independent from the number of days in a month.
Find more info in this API doc
you can use standard class DateTime
require 'date'
dt = Time.new().to_datetime
=> #<DateTime: 2010-04-23T22:31:39+03:00 (424277622199937/172800000,1/8,2299161)>
dt2 = dt >> 1
=> #<DateTime: 2010-05-23T22:31:39+03:00 (424282806199937/172800000,1/8,2299161)>
t = dt2.to_time
=> 2010-05-23 22:31:39 +0200
There are no built-in methods on Time to do what you want in Ruby. I suggest you write methods to do this work in a module and extend the Time class to make their use simple in the rest of your code.
You can use DateTime, but the methods (<< and >>) are not named in a way that makes their purpose obvious to someone that hasn't used them before.
If you do not want to load and rely on additional libraries you can use something like:
module MonthRotator
def current_month
self.month
end
def month_away
new_month, new_year = current_month == 12 ? [1, year+1] : [(current_month + 1), year]
Time.local(new_year, new_month, day, hour, sec)
end
def month_ago
new_month, new_year = current_month == 1 ? [12, year-1] : [(current_month - 1), year]
Time.local(new_year, new_month, day, hour, sec)
end
end
class Time
include MonthRotator
end
require 'minitest/autorun'
class MonthRotatorTest < MiniTest::Unit::TestCase
describe "A month rotator Time extension" do
it 'should return a next month' do
next_month_date = Time.local(2010, 12).month_away
assert_equal next_month_date.month, 1
assert_equal next_month_date.year, 2011
end
it 'should return previous month' do
previous_month_date = Time.local(2011, 1).month_ago
assert_equal previous_month_date.month, 12
assert_equal previous_month_date.year, 2010
end
end
end
below it works
previous month:
Time.now.months_since(-1)
next month:
Time.now.months_since(1)
I just want to add my plain ruby solution for completeness
replace the format in strftime to desired output
DateTime.now.prev_month.strftime("%Y-%m-%d")
DateTime.now.next_month.strftime("%Y-%m-%d")
You can get the previous month info by this code
require 'time'
time = Time.parse('2021-09-29 12:31 UTC')
time.prev_month.strftime("%b %Y")
You can try convert to datetime.
Time gives you current date, and DateTime allows you to operate with.
Look at this:
irb(main):041:0> Time.new.strftime("%d/%m/%Y")
=> "21/05/2015"
irb(main):040:0> Time.new.to_datetime.prev_month.strftime("%d/%m/%Y")
=> "21/04/2015"
Here is a solution on plain ruby without RoR, works on old ruby versions.
t=Time.local(2000,"jan",1,20,15,1,0);
curmon=t.mon;
prevmon=(Time.local(t.year,t.mon,1,0,0,0,0)-1).mon ;
puts "#{curmon} #{prevmon}"
Some of the solutions assume rails. But, in pure ruby you can do the following
require 'date'
d = Date.now
last_month = d<<1
last_month.strftime("%Y-%m-%d")
Im using the ActiveSupport::TimeZone for this example, but just in case you are using Rails or ActiveSupport it might come in handy.
If you want the previous month you can substract 1 month
time = Time.zone.parse('21-12-2008 10:51 UTC')
time.ago(1.month)
$ irb
irb(main):001:0> time = Time.now
=> 2016-11-21 10:16:31 -0800
irb(main):002:0> year = time.year
=> 2016
irb(main):003:0> month = time.month
=> 11
irb(main):004:0> last_month = month - 1
=> 10
irb(main):005:0> puts time
2016-11-21 10:16:31 -0800
=> nil
irb(main):006:0> puts year
2016
=> nil
irb(main):007:0> puts month
11
=> nil
irb(main):008:0> puts last_month
10
=> nil

Ruby - DateTime for Database

I have a Database column with the syntax "0000-00-00 00:00:00".
In PHP I would do
date('Y-m-d H:i:s');
In Ruby, I do
require 'date'
now = DateTime::now()
puts "#{now.year()}-#{now.mon()}-#{now.mday()} #{now.hour()}:#{now.min()}:#{now.sec()}"
The result is:
"2010-1-5 10:16:4"
That's not okay. How could I create a "timestring" with the format "0000-00-00 00:00:00"?
Thanks a lot in advance & Best Regards
You can format the dates like in PHP thanks to the built-in Time class, see documentation there.
This would give for your case :
t = Time.now
puts t.strftime("%Y-%m-%d %H:%M:%S")
A little shorter
t = Time.now
puts t.strftime("%F %T")
=> "2015-01-06 14:01:05"
iso8601 method can be useful also:
>> Time.now.utc.iso8601
=> "2015-05-08T16:45:22Z"
If you're using Rails/ActiveSupport then to_s(:db) will be the shortest way:
Time.now.to_s(:db)
=> "2017-05-22 11:14:40"
ActiveRecord tends to store dates / times as UTC, so using utc will make your data more consistant
t = Time.now.utc
puts t.strftime("%F %T")
=> "2016-05-06 19:05:01"
Note that Rails also stores microsecond precision. That is, microseconds are the 6 digits after the second in the database format:
Time.now.strftime('%Y-%m-%d %H:%M:%S.%6N')
=> "2022-10-26 12:30:26.243506"
or:
Time.now.strftime('%F %T.%6N')
=> "2022-10-26 12:34:37.803091"

Resources