lubridate's force_tz doesn't recognize timezone - timezone

I want to use force_tz() to change the time zone of my ydm_hm() object. My code:
force_tz(ydm_hm("2013-25-07 4:00am"), "Europe/Berlin")
So I tried with other timezones, e.g. "CEST", but it only works with the default "UTC". Here https://rdrr.io/cran/lubridate/man/force_tz.html it says, these should all be interpretable. The error message I get is:
Error in C_force_tz(time, tz = tzone, roll) :
CCTZ: Unrecognized output timezone: "Europe/Berlin"
Thank you for any help!

Hm, weird. I cannot replicate your error message (working on Win10):
library(lubridate)
x <- ydm_hm("2013-25-07 4:00am")
x
#> [1] "2013-07-25 04:00:00 UTC"
force_tz(x, "Europe/Berlin")
#> [1] "2013-07-25 04:00:00 CEST"
force_tz(x, "etc/GMT-1")
#> [1] "2013-07-25 04:00:00 +01"
Created on 2022-10-14 with reprex v2.0.2
If you're working on macOS, this post might help eventually. Also, in case you updated R currently, have you tried re-installing lubridate (c.f. here)?

Related

Decoding the expiry date of a JavaScript Web Token (JWT)?

I am unable to understand the expiry date format of the JWT embedded in my application.
For example: 1473912000
What does this translate to? 1473912000 ms, some x date? Any help will be appreciated!
Like James has pointed out:
The number is the number of seconds since Jan 1 1970.
This is converted into the Date object in a quite straight-forward way (the *1000 part is here because in JS main time unit is millisecond):
const expiryDate = new Date(1473912000*1000);
Then you can use any Date method you please.
Likewise, in Ruby you can use Time.at(1473912000) to create a new Time instance like Maxim has shown.
The number is the number of seconds since Jan 1 1970. It is commonly used on unix systems to represent time. Your time is 2016-09-15 04:00 (UTC)
To convert you can try a web based system http://www.unixtimestamp.com/index.php
This is UNIX time in seconds:
➜ ~ irb
2.2.0 :001 > Time.at(1473912000)
=> 2016-09-15 07:00:00 +0300

Parse a date with too many days in month

Is there any way to correctly parse a date that has too many days in the month? E.g.
'2016-01-32' = '2016-02-01'
'2015-12-32' = '2016-01-01'
This is to support easy date manipulation on some of my JS based front-end.
This is with Ruby 2.3.0 and Rails 4.2.5. I think this was working in an earlier release - perhaps the parsing rules were tightened?
I'd rather rely on a standard library and it's knowledge of leap years etc, rather than implementing this myself.
You can use Date::_parse (or Date::_iso8601) to parse a date string without validation:
require 'date'
h = Date._parse('2016-01-32')
#=> {:mday=>32, :year=>2016, :mon=>1}
And create a date instance using Simone Carletti's suggestion:
Date.new(h[:year], h[:mon]).next_day(h[:mday] - 1)
#=> #<Date: 2016-02-01 ...>
If both, days and months can be out of range, you could use:
h = Date._parse('2016-14-32')
#=> {:mday=>32, :year=>2016, :mon=>14}
Date.new(h[:year]).next_month(h[:mon] - 1).next_day(h[:mday] - 1)
#=> #<Date: 2017-03-04 ...>
next_day and next_month are equivalent to + and << respectively, so the last line can also be written as:
Date.new(h[:year]) << (h[:mon] - 1) + (h[:mday] - 1)
or:
Date.new(h[:year]) << h[:mon].pred + h[:mday].pred
require 'date'
y, m, d = '2016-01-32'.split('-').map(&:to_i)
# => [2016, 01, 32]
last_day_of_month = Date.civil(y, m, -1)
# => #<Date: 2016-01-31 ((2457419j,0s,0n),+0s,2299161j)>
date = last_day_of_month + (d - last_day_of_month.day)
# => #<Date: 2016-02-01 ((2457420j,0s,0n),+0s,2299161j)>
Trying to parse a date like the one you mentioned will raise an error
DateTime.parse('2016-01-32')
ArgumentError: invalid date
One possible solution is to create a custom function/class for date parsing. You forward the parse to the DateTime object, if it fails with that error, you can retry by stripping the day number and replacing it with 1.
If it succeeds, you add the remaining days to the date.
date = DateTime.parse('2016-01-1')
=> Fri, 01 Jan 2016 00:00:00 +0000
date + (32-1).days
=> Mon, 01 Feb 2016 00:00:00 +0000
No existing core or Rails library will do that automatically for you. Hence you need a custom function for that.
You should be able to easily write the method following the instructions and the example above.
Here is one way to do it:
require 'date'
date_string = '2016-01-50'
year,month,day = date_string.split('-').map(&:to_i)
date = Date.new(year,month)
(day-1).times{date = date.next}
p date #=> 2016-02-19

.to_time different movement from documentation

I use rails4.2.4
My application.rb
config.time_zone = 'Tokyo'
Doc
http://api.rubyonrails.org/classes/String.html#method-i-to_time
say
"2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100
"2012-12-13T06:12".to_time(:utc) # => 2012-12-13 05:12:00 UTC
My code
I try this
p "2012-12-13T06:12".to_time
p "2012-12-13T06:12".to_time(:utc)
result
2012-12-13 06:12:00 +0900
2012-12-13 06:12:00 UTC
Summary
document say 2012-12-13 05:12:00 UTC
my code say 2012-12-13 06:12:00 UTC
doc 1 hour diffrence.
but my code same( I think occur 9 hours difference ).
Most likely it's just a typo in documentation. Because date/time in a string doesn't tell anything about time zone. So you can either assume it's a local time with .to_time(which is .to_time(:local)) or that this time is in UTC with .to_time(:utc) depending on application needs.

How to convert a long to date?

I have a long value in Rails, 134740800, which is the number of milliseconds since the epoch.
How do I convert that to a date in mm-dd-yyyy format?
I figure the formatting would be done with something like strftime but I can't seem to find the right method to convert the long into a valid date.
secs = 134740800/1000 # millisecs / 1000
t = Time.at(secs)
t.strftime("%m-%d-%Y")
Output
"01-02-1970"
Try this:
require 'date'
DateTime.strptime("1318996912",'%s')
I assume you mean seconds since the epoch.
Time.at seconds_since_epoch
You can also pass a float. If you have milliseconds, divide by 1000.0 first.
You can then call strftime on the returned Time object.
Use Time.at:
irb(main):003:0> Time.at(134740800)
=> Tue Apr 09 08:00:00 -0400 1974
This is an advisory... It's often a good idea to look at how fast some answers run. Here's a simple benchmark:
require 'benchmark'
require 'date'
SECS = 134740800
LOOPS = 1_000_000
puts Time.at(SECS).strftime('%m-%d-%Y')
puts Date.strptime(SECS.to_s, '%s').strftime('%m-%d-%Y')
Benchmark.bm(14) do |x|
x.report('Time.at:') { LOOPS.times { Time.at(SECS) }}
x.report('Date.strptime:') { LOOPS.times { Date.strptime(SECS.to_s, '%s') }}
end
And the output is:
04-09-1974
04-09-1974
user system total real
Time.at: 0.370000 0.020000 0.390000 ( 0.392761)
Date.strptime: 6.320000 0.050000 6.370000 ( 6.373248)

How do I convert a 'Fixnum' to a date in Rails 3.1.3?

I am trying to display this output, as a date:
1296524384
But when I call .to_date on it, I am getting this error:
undefined method `to_date' for 1296524384:Fixnum
You can just do:
the_time = Time.at(1296524384)
That gives you:
2011-01-31 20:39:44 -0500
By the way, 1296524384 is referred to as UNIX or epoch time. It measures the number of seconds elapsed since January 1, 1970.
To format it a bit better, you can use Ruby's strftime method.
the_time = Time.at(1296524384).strftime("The date is %m/%d/%Y")
More info here: http://apidock.com/ruby/DateTime/strftime

Resources