Open Dan2552 opened 11 years ago
The current version uses a deprecated conversion, 'NSDate.dateWithNaturalLanguageString:`. There's been some discussion about whether this kind of date conversion actually belongs here, but I came up with another solution, which I proposed to @colinta for SugarCube. You can see it here:
https://github.com/rubymotion/sugarcube/blob/master/lib/sugarcube/date_parser.rb
def cast_to_date(arg)
case arg
when String
return NSDate.dateWithNaturalLanguageString(arg.gsub('-','/'), locale:NSUserDefaults.standardUserDefaults.dictionaryRepresentation)
when Time
return NSDate.dateWithNaturalLanguageString(arg.strftime('%Y/%m/%d %H:%M'), locale:NSUserDefaults.standardUserDefaults.dictionaryRepresentation)
else
return arg
end
end
I do consider this an issue in MotionModel, and if you want a quick fix, there are two paths to take:
Do the cast yourself. I.e., my_model.my_date = MakeADateOutOf(my_form_data)
-or-
Try overriding the cast:
module MotionModel
module Model
def cast_to_date(arg)
case arg
when String
return arg.to_date # uses the SugarCube data detector
when Time
return arg.strftime('%Y/%m/%d %H:%M').to_date # uses the SugarCube data detector
else
return arg
end
end
end
end
I haven't tried this, but I did supply specs for the SugarCube implementation.
If you know your date will always be in the 8601 format, you might be able to use Time.parse
.
I'll leave this issue open until I can get it "fixed".
turns out Sugarcube doesn't like 8601 either
(main)> SugarCube::DateParser.parse_date("2013-04-01T09:00:00+01:00")
=> 2013-04-01 00:00:00 +0100
If anybody else comes across this, seems you can use NSDateFormatter:
> formatter = NSDateFormatter.new
> formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
> formatter.dateFromString "2013-04-01T09:00:00+01:00"
=> 2013-04-01 09:00:00 +0100
Then it's not SugarCube -- it's Apple's data detector. Time.parse does understand 8601 according to the documentation. Have you given this a try? Again, if you absolutely know it's 8601, you have significant latitude to override this cast method in MotionModel.
On Apr 1, 2013, at 11:38 AM, Dan2552 notifications@github.com wrote:
turns out Sugarcube doesn't like 8601 either
(main)> SugarCube::DateParser.parse_date("2013-04-01T09:00:00+01:00") => 2013-04-01 00:00:00 +0100 — Reply to this email directly or view it on GitHub.
Where is Time.parse
supposed to be defined? I get
#<NoMethodError: undefined method `parse' for Time:Class>
Bubblewrap has an iso8601 method, alas it doesn't like the time zone
> Time.iso8601 "2012-05-31T19:41:33Z"
=> 2012-05-31 21:41:33 +0200
> Time.iso8601 "2013-04-01T09:00:00+0100"
=> nil
I'm personally fine with using the NSDateFormatter
way that I added earlier (I just had a thought that you maybe missed my edit if you were replying by email rather than web)
Arrrrgh. Ruby 1.8.7 Docs point to this:
http://ruby-doc.org/stdlib-1.8.7/libdoc/time/rdoc/Time.html#method-c-parse
Ruby 1.9.2 docs point to this:
http://ruby-doc.org/stdlib-1.9.2/libdoc/time/rdoc/Time.html#method-c-parse
However... This appears not to have been implemented in RubyMotion as Time is a wrapper for NSDate. I think that's the wrong answer and submitted a ticket: [#648] Time.parse is not implemented.
In the meantime, try this:
class Time def self.from_8601(str) regex8601 = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.)(\d{2})(\d{2})/ matches = str.match(regex8601) return nil if matches.nil? time = Time.new(matches[1].to_i, matches[2].to_i, matches[3].to_i, matches[4].to_i, matches[5].to_i, matches[6].to_i, matches[7] + matches[8] + ':' + matches[9] ) end end
On Apr 1, 2013, at 12:54 PM, Dan2552 notifications@github.com wrote:
Where is Time.parse supposed to be defined? I get
<NoMethodError: undefined method `parse' for Time:Class>
— Reply to this email directly or view it on GitHub.
Follow-up to this. HipByte points out, correctly, that Time.parse is in stdlib and not core. Looks like we'll have to roll our own solutions here.
I'll leave this issue open for discussion about what kind of date input MotionModel should recognize:
One place to put core extensions is in the active_support gem (https://github.com/hookercookerman/motion_support). That takes the date-related concerns outside of the data-modeling domain and places it in a more logical location.
On Apr 1, 2013, at 2:03 PM, Steve Ross sxross@gmail.com wrote:
Arrrrgh. Ruby 1.8.7 Docs point to this:
http://ruby-doc.org/stdlib-1.8.7/libdoc/time/rdoc/Time.html#method-c-parse
Ruby 1.9.2 docs point to this:
http://ruby-doc.org/stdlib-1.9.2/libdoc/time/rdoc/Time.html#method-c-parse
However... This appears not to have been implemented in RubyMotion as Time is a wrapper for NSDate. I think that's the wrong answer and submitted a ticket: [#648] Time.parse is not implemented.
In the meantime, try this:
class Time def self.from_8601(str) regex8601 = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.)(\d{2})(\d{2})/ matches = str.match(regex8601) return nil if matches.nil? time = Time.new(matches[1].to_i, matches[2].to_i, matches[3].to_i, matches[4].to_i, matches[5].to_i, matches[6].to_i, matches[7] + matches[8] + ':' + matches[9] ) end end
On Apr 1, 2013, at 12:54 PM, Dan2552 notifications@github.com wrote:
Where is Time.parse supposed to be defined? I get
<NoMethodError: undefined method `parse' for Time:Class>
— Reply to this email directly or view it on GitHub.
You may want to have a look at https://github.com/archan937/MocRuby/blob/master/lib/moc_ruby/mocks/mac_ruby-0.12/time.rb.
This and lock-o-motion are becoming valuable additions to my project. I think there may be a lot of MacRuby code that can be leveraged, and good for it to come from a common place.
IMO parsing RFC dates is one thing, natural language is entirely another. I always vote for being explicit on format expectations as incorrect results often go unnoticed.
On Monday, April 1, 2013 at 2:36 PM, s.ross wrote:
Follow-up to this. HipByte points out, correctly, that Time.parse is in stdlib and not core. Looks like we'll have to roll our own solutions here.
I'll leave this issue open for discussion about what kind of date input MotionModel should recognize:
- arbitrary user strings like "tomorrow", "12/18/16", "three days from now"
- specific strings like rfc8601 (and others?)
- none of the above
- all of the above
One place to put core extensions is in the active_support gem (https://github.com/hookercookerman/motion_support). That takes the date-related concerns outside of the data-modeling domain and places it in a more logical location.
On Apr 1, 2013, at 2:03 PM, Steve Ross <sxross@gmail.com (mailto:sxross@gmail.com)> wrote:
Arrrrgh. Ruby 1.8.7 Docs point to this:
http://ruby-doc.org/stdlib-1.8.7/libdoc/time/rdoc/Time.html#method-c-parse
Ruby 1.9.2 docs point to this:
http://ruby-doc.org/stdlib-1.9.2/libdoc/time/rdoc/Time.html#method-c-parse
However... This appears not to have been implemented in RubyMotion as Time is a wrapper for NSDate. I think that's the wrong answer and submitted a ticket: [#648] Time.parse is not implemented.
In the meantime, try this:
class Time
def self.from_8601(str)
regex8601 = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.)(\d{2})(\d{2})/
matches = str.match(regex8601)
return nil if matches.nil?
time = Time.new(matches[1].to_i,
matches[2].to_i,
matches[3].to_i,
matches[4].to_i,
matches[5].to_i,
matches[6].to_i,
matches[7] + matches[8] + ':' + matches[9]
)
end
endOn Apr 1, 2013, at 12:54 PM, Dan2552 <notifications@github.com (mailto:notifications@github.com)> wrote:
Where is Time.parse supposed to be defined? I get
<NoMethodError: undefined method `parse' for Time:Class>
—
Reply to this email directly or view it on GitHub.— Reply to this email directly or view it on GitHub (https://github.com/sxross/MotionModel/issues/29#issuecomment-15738877).
I'm getting weird results with date parsing
edit--- ooer now I'm confused, it uses the NSDate.dateWithNaturalLanguageString method which isn't even an iOS NSDate method but rather an OS X one