Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

[REBOL] Re: Question about date? function

From: joel::neely::fedex::com at: 13-Oct-2001 8:53

Hi, Brock, Brock & Janet wrote:
> Carl, > Thanks. I see how this works. I guess the date? function isn't > really processing the date and is just reporting back validity > for the datatype query... >
Carl's already done a great job with the original question, so I'm just gilding the lilly... May I suggest thinking about DATE? a little differently from your wording above? The reason is that "validity" sounds (at least to my ear) more like some kind of before-the-fact syntax check -- asking if it would be OK to transform an argument into some type *in the future*. The result of DATE? (and his many cousins) is simply telling whether the argument value is *already* of a particular type, because that argument is *already* transformed from external form into some REBOL value. In other words,
>> integer? 123
== true is equivalent to
>> integer! = type? 123
== true and so on for all XXX?/XXX! pairs, so that
>> integer? "123"
== false will always be false (no matter what the sequence of characters supplied) because
>> type? "123"
== string! As Carl already pointed out, if you're trying to figure out whether a string *could be* converted to a date (integer, whatever...) in the obvious way, TRY is your friend (unless you want to write your own PARSE rules...). Let me add that if you want to encapsulate that for reuse throughout your script, you might try one of the following. looks-like-a-date: func [s [string!]][ not error? try [to-date s] ] ... just tests whether the string *can be* made into a DATE! value.
>> looks-like-a-date "01/13/25" == false >> looks-like-a-date "01/12/25" == true
On the other hand, try-date: func [s [string!]][ if error? try [return to-date s] [none] ] ... will return you the converted DATE! value or NONE to signal failure.
>> try-date "01/13/25" == none >> try-date "01/12/25" == 1-Dec-2025 >> try-date "001/12/25" == 1-Dec-2025 >> try-date "2001/12/25" == 25-Dec-2001
You can use it "as is" in repeated code cliches, such as ...
>> until [birthday: try-date ask "What's your birthday? "]
What's your birthday? 01/13/25 What's your birthday? 01/12/25 == 1-Dec-2025 ... or the slightly fancier ...
>> while [
[ none? birthday: try-date ask "What's your birthday? " [ ][ [ print "^-Please try yyyy-mm-dd format" [ ] print ["^-Ah," birthday "is a nice date!"] What's your birthday? 01/13/25 Please try yyyy-mm-dd format What's your birthday? 25/01/13 Ah, 25-Jan-2013 is a nice date! Following the DRY principle (Don't Repeat Yourself), you can turn all of the above into a re-usable function ... get-a-date: func [ prompt [string!] /local result ][ while [ none? result: try-date ask prompt ][ print "^-Please try yyyy-mm-dd format" ] result ] ... which, of course, does this ...
>> get-a-date "What's your birthday? "
What's your birthday? 1/13/25 Please try yyyy-mm-dd format What's your birthday? 2001/13/25 Please try yyyy-mm-dd format What's your birthday? 2001/12/25 == 25-Dec-2001 By now I'm sure I've beaten this poor issue to death, but I wanted to think through the kind of refactoring that I often use to "grow" reusable ideas/functions in REBOL, which (within certain bounds) is quite handy for this kind of stream-of-consciousness evolution. Of course, I apologize if I've insulted your intelligence or experience! ;-) Happy REBOLing! -jn- -- ; sub REBOL {}; sub head ($) {@_[0]} REBOL [] # despam: func [e] [replace replace/all e ":" "." "#" "@"] ; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"} print head reverse despam "moc:xedef#yleen:leoj" ;