Convert Ruby Date to Integer
Date cannot directly become an integer. Ex:
$ Date.today
=> #<Date: 2017-12-29 ((2458117j,0s,0n),+0s,2299161j)>
$ Date.today.to_i
=> NoMethodError: undefined method 'to_i' for #<Date: 2017-12-29 ((2458117j,0s,0n),+0s,2299161j)>
Your options are either to turn the Date into a time then an Int which will give you the seconds since epoch:
$ Date.today.to_time.to_i
=> 1514523600
Or come up with some other number you want like days since epoch:
$ Date.today.to_time.to_i / (60 * 60 * 24) ### Number of seconds in a day
=> 17529 ### Number of days since epoch
How do I convert this Time integer to a Date in Ruby?
Use Time.at
for this:
t = Time.at(i)
Convert number to date in Ruby
DateTime.strptime('1512387277084', '%Q')
#⇒ #<DateTime: 2017-12-04T11:34:37+00:00
# ((2458092j,41677s,84000000n),+0s,2299161j)>
DateTime
formatting.
Convert to/from DateTime and Time in Ruby
You'll need two slightly different conversions.
To convert from Time
to DateTime
you can amend the Time class as follows:
require 'date'
class Time
def to_datetime
# Convert seconds + microseconds into a fractional number of seconds
seconds = sec + Rational(usec, 10**6)
# Convert a UTC offset measured in minutes to one measured in a
# fraction of a day.
offset = Rational(utc_offset, 60 * 60 * 24)
DateTime.new(year, month, day, hour, min, seconds, offset)
end
end
Similar adjustments to Date will let you convert DateTime
to Time
.
class Date
def to_gm_time
to_time(new_offset, :gm)
end
def to_local_time
to_time(new_offset(DateTime.now.offset-offset), :local)
end
private
def to_time(dest, method)
#Convert a fraction of a day to a number of microseconds
usec = (dest.sec_fraction * 60 * 60 * 24 * (10**6)).to_i
Time.send(method, dest.year, dest.month, dest.day, dest.hour, dest.min,
dest.sec, usec)
end
end
Note that you have to choose between local time and GM/UTC time.
Both the above code snippets are taken from O'Reilly's Ruby Cookbook. Their code reuse policy permits this.
Ruby - Convert Day Of Week To Integer
You can parse it using strptime
:
Date.strptime('Monday', '%A').wday
#=> 1
Date.strptime('Wednesday', '%A').wday
#=> 3
The intermediate date object refers to the weekday in the current week:
Date.today
#=> #<Date: 2018-11-20 ...>
Date.strptime('Monday', '%A')
#=> #<Date: 2018-11-19 ...>
You can also use _strptime
(prefixed with an underscore) to extract the date elements which happen to be :wday
for a single weekday:
Date._strptime('Monday', '%A')
#=> {:wday=>1}
How Do I Convert a Month Name into a Month Integer in Ruby?
Use Date::MONTHNAMES:
Date::MONTHNAMES.index("June")
=> 6
Also note there is an equivalent for abbreviated month-names - Date::ABBR_MONTHNAMES:
Date::ABBR_MONTHNAMES.index("Jun")
=> 6
Create TimeWithZone object from integer (unix epoch time with millisecond precision) and with specified zone (string)
Assuming that the timestamp is in milliseconds, then 1586653140000 is
Epoch: 1586653140
GMT: Sunday, April 12, 2020 12:59:00 AM
PDT: Saturday, April 11, 2020 17:59:00 PM -in time zone America/Los Angeles
These are just 3 different ways to refer to a specific point in time around the world.
Sat, 11 Apr 2020 20:59:00 PDT -07:00 and 2020-04-11 20:59:00 -0400 each refer to different points in time and not the same as epoch(1586653140)
Since the Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), it wouldn't make sense to take 1586653140
and only change the time zone without adding the zone's offset because now you are talking about another point in time.
To get the right "translation" from the epoch to any time zone you could just do
Time.zone = "GMT"
Time.zone.at(1586653140)
=> Sun, 12 Apr 2020 00:59:00 GMT +00:00
Time.zone = "America/Los_Angeles"
Time.zone.at(1586653140)
=> Sat, 11 Apr 2020 17:59:00 PDT -07:00
When working with dates in time zones in rails it is important to only use functions that take the set time zone into account:
DON’T USE
- Time.now
- Date.today
- Date.today.to_time
- Time.parse("2015-07-04 17:05:37")
- Time.strptime(string, "%Y-%m-%dT%H:%M:%S%z")
DO USE
- Time.current
- 2.hours.ago
- Time.zone.today
- Date.current
- 1.day.from_now
- Time.zone.parse("2015-07-04 17:05:37")
- Time.strptime(string, "%Y-%m-%dT%H:%M:%S%z").in_time_zone
Also keep in mind that in a Rails app, we have three different time zones:
- system time,
- application time, and
- database time.
This post by thoughtbot explains things clearly.
Related Topics
Selenium Rc: Run Tests in Multiple Browsers Automatically
Install Ruby Curb Gem in Windows Xp
Establish a Connection to Another Database Only in a Block
Is There a Way Rails 3.0.X Can Default to Using Thin
How to Make Carrierwave Delete the File When Destroying a Record
Has_Many While Respecting Build Strategy in Factory_Girl
Creating a Capistrano Task That Performs Different Tasks Based on Role
Regex Match Everything Up to First Period
Redis or Mongo for Determining If a Number Falls Within Ranges
Custom Ruby Gem in Gemfile on Heroku
Undef - Why Would You Want to Undefine a Method in Ruby
Suppressing the Output of a Command Run Using 'System' Method While Running It in a Ruby Script
How to Specify Output File Encoding in Ruby
Devise: How to Override Devise Error Messages on Password Change