Time.local vs Time.new
Both method return Time object.
irb(main):005:0> Time.new(2020,1,1).class
=> Time
irb(main):006:0> Time.local(2020, 1, 1).class
=> Time
irb(main):007:0> Time.local(2020, 1, 1)
=> 2020-01-01 00:00:00 +0900
irb(main):008:0> Time.new(2020,1,1)
=> 2020-01-01 00:00:00 +0900
irb(main):009:0>
I don't know when should I use each method.
Time.local vs Time.new
Time.local will give error if no argument is given, whereas Time.new is initialized to the current system time if no argument is given.
Time.local will always return values in the local time zone. Time.new accepts the timezone parameter & if given returns the value in in the respective time zone.
Check this
2.5.1 :018 > Time.new.zone
=> "IST"
2.5.1 :019 > Time.new
=> 2020-11-18 19:50:30 +0530
2.5.1 :020 > Time.local
Traceback (most recent call last):
3: from /Users/salilgaikwad/.rvm/rubies/ruby-2.5.1/bin/irb:11:in `<main>'
2: from (irb):20
1: from (irb):20:in `local'
ArgumentError (wrong number of arguments (given 0, expected 1..8))
2.5.1 :021 > Time.new(2020,11,18,15,25,0, "+09:00")
=> 2020-11-18 15:25:00 +0900
2.5.1 :022 > Time.local(2020,11,18,15,25,0, "+09:00")
=> 2020-11-18 15:25:00 +0530
It looks like you must pass arguments to #local,r whereas you don't need to pass arguments to #new and it would return current time.
Related
I have a ruby hash
input = {"dateCreated"=>#<BSON::Timestamp:0x00007fe0b482ca98 #increment=3745289216, #seconds=229>}
how do we extract time from BSON timestamp class.
tried input["dateCreated"].as_json
=> {"$timestamp"=>{"t"=>244, "i"=>664779776}}
Not sure how to proceed.
Also would appreciate if there is any pointer on how to filter based on timestamp value to MongoDB using ruby driver
.find() method
You can convert a BSON::Timestamp to a BSON::ByteBuffer using the #to_bson method.
You can then convert the BSON::ByteBuffer to an integer (#get_int64) that represents the number of milliseconds since the epoch.
Then use Time::at to convert that integer to a Time object
date_time = DateTime.new(2021,8,30)
date_time.to_time
#=> 2021-08-30 00:00:00 +0000
date_time.to_time.to_i
#=> 1630281600
timestamp = BSON::Timestamp.from_bson(date_time.to_bson)
#=> #<BSON::Timestamp:0x00007fffe31da4a8 #seconds=379, #increment=2488994816>
timestamp.to_bson.get_int64 / 1000
#=> 1630281600
Time.at(timestamp.to_bson.get_int64 / 1000).utc
#=> 2021-08-30 00:00:00 UTC
It seems that you hace an object of this type:
https://www.rubydoc.info/github/mongodb/bson-ruby/BSON/Timestamp
from this gem
and this object
[6] pry(main)> bt = BSON::Timestamp.new(229, 3745289216)
=> #<BSON::Timestamp:0x00007fe338a79680 #increment=3745289216, #seconds=229>
[7] pry(main)> # you allready have when begin the object in second 229
[8] pry(main)> # you allready have when finish the even in secons in atribute increment 3745289216
may be this value are chage because time begins in 1970 son for translating settings and using a handy gem for manipulating times used in rails:
[10] pry(main)> DateTime.strptime(bt.seconds.to_s,'%s')
=> #<DateTime: 1970-01-01T00:03:49+00:00 ((2440588j,229s,0n),+0s,2299161j)>
[13] pry(main)> require 'active_support/core_ext/numeric/time.rb'
=> true
[14] pry(main)> DateTime.strptime(bt.seconds.to_s,'%s') + bt.increment.seconds
=> Mon, 06 Sep 2088 06:10:45 +0000
I have a time stamp I am obtaining from an Access database. Unfortunately, the timestamp represents the time only, but is stored as 1899-12-30 13:05:00 +0000. The date part of it is in a different field. I need to preserve the data as much as possible while I am storing it in a json blob.
I am using Oj (which is wonderful) to dump the data to json. I have encountered the following behavior on the Windows platform:
irb(main):001:0> require 'oj'
=> true
irb(main):002:0> t = Time.new(1899,12,30,13,5,0) #this is my actual timestamp
=> 1899-12-30 13:05:00 +0000
irb(main):003:0> Oj.dump(t)
RangeError: bignum too big to convert into `long'
from (irb):3:in `dump'
from (irb):3
from C:/RailsInstaller/Ruby2.2.0/bin/irb:11:in `<main>'
irb(main):004:0>
Now, on linux:
2.3.0 :001 > require 'oj'
=> true
2.3.0 :002 > t = Time.new(1899,12,30,13,5,0)
=> 1899-12-30 13:05:00 +0000
2.3.0 :003 > Oj.dump(t)
=> "{\"^t\":-2209114500.000000000e0}"
I need to make this work on Windows because my source database is MS Access. Please help.
Time is not handled properly, but you can convert to float. The result string differ a bit from your original:
irb(main):001:0> require 'oj'
=> true
irb(main):002:0> t = Time.new(1899,12,30,13,5,0)
=> 1899-12-30 13:05:00 +0100
irb(main):003:0> Oj.dump(t)
RangeError: bignum too big to convert into `long'
from (irb):3:in `dump'
from (irb):3
from C:/Ruby23-x64/bin/irb.cmd:19:in `<main>'
irb(main):005:0> Oj.dump(t.to_f)
=> "-2209118100.0"
Or if you need the exact response you can use an array:
irb(main):001:0> require 'oj'
=> true
irb(main):002:0> t = Time.new(1899,12,30,13,5,0)
=> 1899-12-30 13:05:00 +0100
irb(main):012:0> A1 = Array.new(1)
=> [nil]
irb(main):017:0> A1[0] = '^t'
=> "^t"
irb(main):028:0> A1[1] = t.to_f
=> "-2209118100.0"
irb(main):035:0> Oj.dump(A1).tr("[","{").tr("]","}")
=> "{\"^t\",\"-2209118100.0\"}"
I have an XML file which has a datetime value. I loop through the elements and get the attribute value timeutc.
I managed to convert it to local time zone, but what I am trying to do is convert it to any time zone, PST, CST, EST.
$Appointments = '<appointments><appointment timeutc="2013-10-10T06:00:00" /><appointment timeutc="2013-10-10T06:00:00" /><appointment timeutc="2013-10-10T15:00:00" /></appointments>'
index = 0
doc = REXML::Document.new("#{$Appointments}")
doc.elements.each("appointments/appointment") do |element|
index += 1
value = element.attribute("timeutc").value
to_datetime = DateTime.parse(value).to_s
to_UTC = Time.iso8601(to_datetime).to_s
local_time = Time.iso8601(to_datetime).localtime
puts local_time # => 2013-10-09 23:00:00 -0700
puts local_time.strftime("%A") # => Wednesday
puts local_time.strftime("%B") # => October
puts local_time.strftime("%-d") # => 9
puts local_time.strftime("%l") # => 11
puts local_time.strftime("%M") # => 00
puts local_time.strftime("%p") # => PM
end
You could use the in_time_zone method:
For CST:
local_time.in_time_zone('Central Time (US & Canada)')
For PST:
local_time.in_time_zone('Pacific Time (US & Canada)')
For EST:
local_time.in_time_zone('Eastern Time (US & Canada)')
Ruby's support for time zones hasn't been that great (not sure if this has changed with 2.0), hence the various ActiveSupport libs.
Ruby looks to the environment variable TZ to determine what zone to operate in:
irb [1.9.3]$ ENV["TZ"] # Ruby will look elsewhere and see that I'm in NYC
=> nil
irb [1.9.3]$ Time.iso8601 "2013-10-10T06:00:00"
=> 2013-10-10 06:00:00 -0400
irb [1.9.3]$ ENV["TZ"]="America/Los_Angeles"
=> "America/Los_Angeles"
irb [1.9.3]$ Time.now.zone
=> "PDT"
irb [1.9.3]$ Time.iso8601 "2013-10-10T06:00:00"
=> 2013-10-10 06:00:00 -0700
So... while I'd strongly encourage using the active support methods, you could use something like this:
irb [1.9.3]$ def parse_in_zone(date, zone)
1{ old = ENV["TZ"]
1{ ENV["TZ"] = zone
1{ Time.iso8601 date
1{ ensure
1* ENV["TZ"] = old
1{ end
=> nil
irb [1.9.3]$ parse_in_zone "2013-10-10T06:00:00", "America/Los_Angeles"
=> 2013-10-10 06:00:00 -0700
irb [1.9.3]$ parse_in_zone "2013-10-10T06:00:00", "America/New_York"
=> 2013-10-10 06:00:00 -0400
Also note that DateTime.parse(value) is not necessary. It considers the string's zone when parsing the date:
irb [1.9.3]$ DateTime.parse("2013-10-10T06:00:00").zone
=> "+00:00"
irb [1.9.3]$ DateTime.parse("2013-10-10T06:00+04:00").zone
=> "+04:00"
irb [1.9.3]$ DateTime.parse("2013-10-10T06:00+07:00").zone
=> "+07:00"
Note that in your case I don't think the string: 2013-10-10T06:00:00 is a valid iso date/time (extra :00) but it looks like ruby doesn't care:
irb [1.9.3]$ DateTime.parse("2013-10-10T06:00:0000:000000").to_s
=> "2013-10-10T06:00:00+00:00"
How can I find the number of days between two Date objects?
Subtract the beginning date from the end date:
endDate - beginDate
irb(main):005:0> a = Date.parse("12/1/2010")
=> #<Date: 4911063/2,0,2299161>
irb(main):007:0> b = Date.parse("12/21/2010")
=> #<Date: 4911103/2,0,2299161>
irb(main):016:0> c = b.mjd - a.mjd
=> 20
This uses a Modified Julian Day Number.
From wikipedia:
The Julian date (JD) is the interval of time in days and fractions of a day since January 1, 4713 BC Greenwich noon, Julian proleptic calendar.
This may have changed in Ruby 2.0
When I do this I get a fraction. For example on the console (either irb or rails c)
2.0.0-p195 :005 > require 'date'
=> true
2.0.0-p195 :006 > a_date = Date.parse("25/12/2013")
=> #<Date: 2013-12-25 ((2456652j,0s,0n),+0s,2299161j)>
2.0.0-p195 :007 > b_date = Date.parse("10/12/2013")
=> #<Date: 2013-12-10 ((2456637j,0s,0n),+0s,2299161j)>
2.0.0-p195 :008 > a_date-b_date
=> (15/1)
Of course, casting to an int give the expected result
2.0.0-p195 :009 > (a_date-b_date).to_i
=> 15
This also works for DateTime objects, but you have to take into consideration seconds, such as this example
2.0.0-p195 :017 > a_date_time = DateTime.now
=> #<DateTime: 2013-12-31T12:23:03-08:00 ((2456658j,73383s,725757000n),-28800s,2299161j)>
2.0.0-p195 :018 > b_date_time = DateTime.now-20
=> #<DateTime: 2013-12-11T12:23:06-08:00 ((2456638j,73386s,69998000n),-28800s,2299161j)>
2.0.0-p195 :019 > a_date_time - b_date_time
=> (1727997655759/86400000000)
2.0.0-p195 :020 > (a_date_time - b_date_time).to_i
=> 19
2.0.0-p195 :021 > c_date_time = a_date_time-20
=> #<DateTime: 2013-12-11T12:23:03-08:00 ((2456638j,73383s,725757000n),-28800s,2299161j)>
2.0.0-p195 :022 > a_date_time - c_date_time
=> (20/1)
2.0.0-p195 :023 > (a_date_time - c_date_time).to_i
=> 20
In Ruby 2.1.3 things have changed:
> endDate = Date.new(2014, 1, 2)
=> #<Date: 2014-01-02 ((2456660j,0s,0n),+0s,2299161j)>
> beginDate = Date.new(2014, 1, 1)
=> #<Date: 2014-01-01 ((2456659j,0s,0n),+0s,2299161j)>
> days = endDate - beginDate
=> (1/1)
> days.class
=> Rational
> days.to_i
=> 1
How about this?
(beginDate...endDate).count
The Range is a set of unique serials.
And ... is an exclusive Range literal.
So beginDate..(endDate - 1) is same. Except is not.
In case when beginDate equals endDate, first element will be excluded because of uniqueness and ... will exclude last one. So if we want to .count dates between today and today it will return 0.
This worked for me:
(endDate - beginDate).to_i
Try this:
num_days = later_date - earlier_date
all of these steered me to the correct result, but I wound up doing
DateTime.now.mjd - DateTime.parse("01-01-1995").mjd
days = (endDate - beginDate)/(60*60*24)
Well, take care of what you mean by "between" too...
days_apart = (to - from).to_i # from + days_apart = to
total_days = (to - from).to_i + 1 # number of "selected" days
in_between_days = (to - from).to_i - 1 # how many days are in between from and to, i.e. excluding those two days
I want to subtract the result of File.mtime and Date.today. Time and weekends are ignored. I am after something like
Date.today - File.mtime
File.mtime gives me Fri Oct 08 11:00:18 +1100 2010
and
Date.today 2010-10-11
I thought that to_s() would work for me but File.mtime(filename).to_s gives me the same result like File.mtime(filename)
any idea how I can get the desired date format from File.mtime? And why to_s is not working?
Something like this?
irb(main):001:0> File.mtime("file")
=> 2010-10-08 17:56:10 +0800
irb(main):002:0> File.mtime("file").year
=> 2010
irb(main):003:0> File.mtime("file").month
=> 10
irb(main):004:0> File.mtime("file").day
=> 8
Similarly with Date
irb(main):001:0> require 'date'
=> true
irb(main):002:0> Date.today
=> #<Date: 2010-10-11 (4910961/2,0,2299161)>
irb(main):003:0> Date.today.year
=> 2010
irb(main):004:0> Date.today.month
=> 10
irb(main):005:0> Date.today.day
=> 11
Or you can use strftime
irb(main):001:0> File.mtime("file").strftime("%Y-%m-%d")
=> "2010-10-08"
Try using Time.now and convert to days manually:
age = Time.now - File.mtime(filename)
age_in_days = (age / 24*60*60).to_i