4

I try to parse a text representation of a time into a ruby Time object.

Normally in ruby I would do it like this:

require 'time'
Time.parse('2010-12-15T13:16:45Z')
# => 2010-12-15 13:16:45 UTC

In RubyMotion I am unable to require libs and Time.parse is not available:

(main)> require 'time'
=> #<RuntimeError: #require is not supported in RubyMotion>
(main)>
(main)> Time.parse
=> #<NoMethodError: undefined method `parse' for Time:Class>

Is there a way to require the time library provided by ruby without having to copy and rewrite the whole code to make it compatible with RubyMotion?

mordaroso
  • 1,550
  • 1
  • 11
  • 10
  • Unable to require libs? If true you should run away from it screaming. – pguardiario May 23 '12 at 11:01
  • @pguardiario You can use 3rd party libraries by vendoring them ([see docs](http://www.rubymotion.com/developer-center/guides/project-management/#_using_3rd_party_libraries)). I could copy time.rb from ruby1.9 and remove the `require 'date'` statement. But I hope there is a better/easier way to do this. – mordaroso May 23 '12 at 11:08
  • You should have full access to iOS SDK. There are time parsing functions there. – Sergio Tulentsev May 23 '12 at 11:21
  • You need to use the same APIs Objective-C uses for some things, so `NSDate` and `NSDateFormatter` will get the job done. – leemeichin May 23 '12 at 11:22

4 Answers4

11

It's not as automatic, but you could use NSDateFormatter

date_formatter = NSDateFormatter.alloc.init
date_formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
date = date_formatter.dateFromString "2010-12-15T13:16:45Z"
puts date.description
Paul.s
  • 38,494
  • 5
  • 70
  • 88
  • Thanks, that works. `date` is already a Time object if you do it like this. `date.class.ancestors #=> [Time, Comparable, NSDate, NSObject, Kernel]` – mordaroso May 23 '12 at 11:31
11

While Paul.s answer certainly works, it was giving me the creeps, looking at it in my code, so I kept looking.

Matt Aimonetti's MacRuby book has some good stuff:

http://books.google.ca/books?id=WPhdPzyU1R4C&pg=PA43&lpg=PA43&dq=macruby+nsdate&source=bl&ots=j7Y3J-oBcV&sig=FTr0KyKae-FinH-HNEWBcAAma1s&hl=en&sa=X&ei=ANT0T7mkEM6jqwHx7LjeAw&ved=0CGEQ6AEwBA#v=onepage&q=macruby%20nsdate&f=false

Where parsing is as simple as:

NSDate.dateWithString(<your date string here>)

or

NSDate.dateWithNaturalLanguageString(<all kinds of date strings>)

And if you absolutely have to have a Time object from that:

Time.at(NSDate.date)
wndxlori
  • 196
  • 2
  • 10
  • Thanks for your additional input. – mordaroso Sep 04 '12 at 09:36
  • I don't think NSDate.dateWithString is available on iOS. Thought I'd flag that since the question was regarding Rubymotion dates and not MacRuby. – Dave Rapin Oct 04 '12 at 18:32
  • 1
    I know it's been a long time, but I thought I'd address Dave's caveat. This works just fine in RubyMotion. – wndxlori Apr 27 '13 at 20:27
  • You are my hero. dateFromString was throwing me nil in an iPhone 4S with iOS 7.1.1. But it worked fine in an iPad 2 and simulators. I changed all that with NSDate.dateWithNaturalLanguageString(string), like you suggested. Worked like a beast! BTW I'm using RubyMotion 2.28. Thanks. (The issue may happen in an iPhone 5 as well, according to this post: http://www.copyquery.com/hardware-dependent-nsdateformatter-datefromstring-bug-returns-nil/) – backslash-f May 23 '14 at 03:46
2

BubbleWrap adds some nice wrappers around this:

Time

The Time Ruby class was added a class level method to convert a iso8601 formatted string into a Time instance.

Time.iso8601("2012-05-31T19:41:33Z")
=> 2012-05-31 21:41:33 +0200

This will give you a NSDate instance, simple as that.

defvol
  • 14,392
  • 2
  • 22
  • 32
0

Maybe this has since been fixed. I'm parsing times in RubyMotion no problem.

(main)> Time.parse("2016-01-21 10:33:07")
=> "2016-01-21 10:33:07 -0800"

RubyMotion 4.8

$ motion --version
4.8
mkirk
  • 3,965
  • 1
  • 26
  • 37