Home   Archive   Permalink

Can R2 use a US date format

I have to work with a date and time that looks like this:
'5/2/2014 13:42'
I have discovered that the to-date function will convert that string directly to a REBOL date; a one-line solution to my problem. BUT, it assumes the date is dd/mm/yyyy when my date is mm/dd/yyyy. So to-date returns Feb-5 instead of May-2.
I know how to 'brute-force' a solution by taking the date apart and putting it back together, but I am wondering if there is some REBOL setting that will make it assume a date is the US format instead of the format used by every other civilized country.
Thank you.

posted by:   Steven White     30-Oct-2015/11:10:45-7:00

Rebol can use the format you're familiar with (2-may-2014 or 2-5-2014) and ISO format (2014-5-2). There's no user setting that I know of to change formats (aside from creating a new date! data type), but the 'brute-force' option should work fine. You could use the following function, for example, to do what you want:
us-date: func [usdate] [
     usdate: head move parse usdate "/" 1
     to-date rejoin [usdate/1 "/" usdate/2 "/" usdate/3 " " usdate/4]
Just stick 'us-date in front of any date formatted the way you've described, and it'll work just like 'to-date:
print new-date: us-date "5/2/2014 13:42"
type? new-date

posted by:   Nick     30-Oct-2015/20:13:30-7:00

And you can manage the logic of the function as needed:
us-date: func [ud] [
     ud: head move parse ud "/" 1
     to-date rejoin [ud/1 "/" ud/2 "/" ud/3 " " either ud/4 [ud/4] [""]]
The variation above allows either of the following formats to be handled properly:
us-date "5/2/2014 13:42"
us-date "5/2/2014"

posted by:   Nick     31-Oct-2015/23:44:34-7:00

I wonder if you might explain your example. I see what it is doing; pulling apart the date, reassembling it, and converting it to a REBOL date. But I don't understand the "move" function. It is not in the function dictionary. The sparse help says "Move a value or span of values in a series." But move what, from where, to where? Here are the pieces of it:
>> usdate: "5/2/2014 13:42"
== "5/2/2014 13:42"
>> parseddate: parse usdate "/"
== ["5" "2" "2014" "13:42"]
>> moveddate: move parseddate 1
== ["2014" "13:42"]
>> probe parseddate
["2" "5" "2014" "13:42"]
== ["2" "5" "2014" "13:42"]
Does that mean move item 1? Move everything after item 1? And what in the code indicates the place to which whatever we are moving is moved? The only thing that makes sense to me is to move the first item over one position. But if that is true, then why is the result of the move function the parseddate starting at the third item?
If I use this, I would like to be able to explain it.    

posted by:   Steven White     26-Feb-2016/18:07:49-8:00

If you type "help move" in the Rebol console, you get:
>> help move
     MOVE source offset /part length /skip size /to
     Move a value or span of values in a series.
     MOVE is a function value.
     source -- Source series (Type: series)
     offset -- Offset to move by, or index to move to (Type: integer)
     /part -- Move part of a series
         length -- The length of the part to move (Type: integer)
     /skip -- Treat the series as records of fixed size
         size -- Size of each record (Type: integer)
     /to -- Move to an index relative to the head of the series
By default, 'move will take the first item in the block and move it over the specified number of positions in the series:
x: ["one" "two" "three" "four" "five" "six"]
move x 2
== ["two" "three" "one" "four" "five" "six"]
In the date code above, the 'move operation just nudges the day value (initially the first item in the parsed series) one position over into the second position, which is where you want it for US date format.
It's not needed in the date example above, but you can specify the starting position for the element to be moved, using 'at:
x: ["one" "two" "three" "four" "five" "six"]
move at x 3 2
== ["one" "two" "four" "five" "three" "six"]
The refinements of 'move allow you to accomplish all sorts of position shifting:
x: ["one" "two" "three" "four" "five" "six"]
move/to (find x "five") 2
print x
Instead of looking up functions on the web, I tend to use the built in 'help, and experiment in the console with small bits of code, to get exactly the desired behavior with any of Rebol's functions/refinements.
Here's another example of 'move in use, shortened from an example at http://re-bol.com/short_rebol_examples.r
view layout [
     t: text-list 550x400
     f: field [if not find t/data v: value [append t/data copy v] show t]
     btn "Del" [remove find t/data t/picked show t]
     btn "Up" [attempt [move/to z: find t/data t/picked (index? z) - 1] show t]
     btn "Down" [attempt [move/to z: find t/data t/picked (index? z) + 1] show t]

posted by:   Nick     28-Feb-2016/8:26:23-8:00

Thank you for that thorough, and timely, explanation. I have been putting off a little project at work because I wasn't sure exactly how to do it, not being completely handy with the "series" datatype. It is a small program to manage a tennis ladder, which is a list of tennis players ordered by ability, where people "down" on the ladder can challenge people "higher" on the ladder, and move up if they win. At the end of every month, the program sweeps through the ladder to find people who haven't played a minimum number of games, and moves them 14 spots down the ladder. You might have written that month-end operation for me in one line of code.    
Regarding your date function, just for the sake of capturing the information I rewrote it for myself in my plodding manner, using a dozen lines of code and a temporary variable (I knew what you did, just not how you did it). Looking at my version, and yours, and your other example in the posting above, I think I understand the blessing and the curse of REBOL, its density.

posted by:   Steven White     29-Feb-2016/9:10:30-8:00