Gossamer Forum
Home : Products : DBMan : Customization :

How to sort by DATE and TIME part 2

Quote Reply
How to sort by DATE and TIME part 2
Well the game_news database is in and working like a charm. Except for the date/time sort.

www.makeitsimple.com/cgi-bin/dbman/game_news/db.cgi?db=default&uid=default&sb=ID&so=descend&view_records=1&ID=*

I gave it a test run and thought it was ok but apparently not. Everything with the date/time subs works except sorting.

Quote:
I forgot to add that the field (PostTime) is where I am using the new date/time sub. So, if you get a chance to try it remember to sort by PostTime.

I did make one change when I put in the subs that you gave me JPD. All I did was swap the month and day positions. I did it in both subs and it didn't kick out any errors. Which leads me to think that there is still a snibit of logic missing.

See if you can spot any problems:

sub get_date {

my ($time) = @_;
($time) | | ($time = time());
my ($sec, $min, $hour, $day, $mon, $year, $dweek, $dyear, $daylight) = localtime($time);
my (@months) = qw!Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec!;
($day < 10) and ($day = "0$day");
$year = $year + 1900;
($sec < 10) and ($sec = "0$sec");
($min < 10) and ($min = "0$min");
($hour < 10) and ($hour = "0$hour");

return "$months[$mon]-$day-$year $hour:$min:$sec";
}

*******************

sub date_to_unix {
# --------------------------------------------------------
# This routine must take your date format and return the time a la UNIX time().# Some things to be careful about..
# int your values just in case to remove spaces, etc.
# catch the fatal error timelocal will generate if you have a bad date..
# don't forget that the month is indexed from 0!
#

my ($date_and_time) = $_[0];
my (%months) =
("Jan" => 0, "Feb" => 1, "Mar" => 2, "Apr" => 3,
"May" => 4, "Jun" => 5, "Jul" => 6, "Aug" => 7, "Sep" => 8,
"Oct" => 9, "Nov" => 10,"Dec" => 11);

my ($date, $time) = split(/ /, $_[0]);
my ($mon, $day, $year) = split(/-/, $date);
my ($hour, $min, $sec) = split(/:/, $time);
unless ($mon and $day and $year) { return undef; }
unless (defined($months{$mon})) { return undef; }
use Time::Local;
eval {
$day = int($day); $year = int($year) - 1900;
$time = timelocal($sec,$min,$hour,$day,$months{$mon},$year);
};

if ($@) { return undef;} # Could return 0 if you want.
return (time);

}

I intentionally shortened the long line so it wouldn't mess up UBB.

JPD, I am hitting the sack, I am fried. Maybe you can spot something that I did wrong or come up with another idea.

No hurry, I figured out a way to temporarily get around the problem by advancing the count# to 2000. All of the new posts are 2000 and up, when I want to add the old records I change the count to the last old record and start filling in the gap. That allows sorting by ID without a problem. Tricky eh? Wink

Wishing you luck!



------------------
Larry "NgtCrwlr" Mingus
www.makeitsimple.com

[This message has been edited by NgtCrwlr (edited May 12, 1999).]

[This message has been edited by NgtCrwlr (edited May 12, 1999).]
Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
One thing I notice is that in the URL you gave, you have "&sb=ID". You need to have the field number, not the name, listed as a "sb."

I'm not sure what the problem is. I don't see a problem with your changing the order of the date elements, but I did only test it with the default order.

I'll see if I can think of any debugging procedures you might try. I can't even think of one of them right now.


------------------
JPD





Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
The missing $ was my fault. I looked at the other thread and saw that I'd left it off. I fixed it.

The timelocal command converts the date and time elements into a number -- the number of seconds since 1-Jan-1970, to be exact. So yes, it does use a number for sorting.

Quote:
Yep, the post field is set to type (Date).

Not to be picking nits, but I have to ask. The field type is set to

date

and not

Date

right?

(I've had too many long debugging sessions only to find out the problem was just that someone was not consistent in the letter cases they used.)



------------------
JPD





Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
You do have the data type set to "date" on the PostDate field, right?

Try making one little change (although I'm not sure it will make a difference -- I'm clutching at straws! Smile ). In the date_to_unix subroutine, change

my ($date, $time) = split(/ /, $_[0]);

to

my ($date, $time) = split(/ /, $date_and_time);

Wait a minute. I think I found it.

return (time);

should be

return ($time);

Did I make that mistake? I'll go back to the other thread and check it out.



------------------
JPD





Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
Yep, the post field is set to type (Date).

I just fixed the $ error and it didn't help. I don't think I will have time this morning to try your new changes but as soon as I get up I will give it a wirl.

One thing that I am curious about is the added time string doesn't the sort routine need additional code to handle the (time)? Or, does the date_to_unix convert it to a number that the sort routine can handle. Just a random thought. Wink

Great catch on the missing $ I don't know how that happend, it sure couldn't have been me. Hah! Ya-right

Have a good one JPD



------------------
Larry "NgtCrwlr" Mingus
www.makeitsimple.com
Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
Here is my config, I shortened the field_name for formating here.

# Database Definition
# --------------------------------------------------------
# Definition of your database. Format is
# field_name =>
['position', 'field_type', 'form-length',
'maxlength', 'not_null', 'default', 'valid_expr']


%db_def = (
ID => [0, 'numer', 5, 8, 1, '', ''],
Headline => [1, 'alpha', 60, 255, 1, '', ''],
URL => [2, 'alpha', 60, 255, 1, '', '^http://'],
Type => [3, 'alpha', 20, 20, 1, 'Review', ''],
Source => [4, 'alpha', 25, 25, 1, '', ''],
Date => [5, 'alpha', 12, 12, 0, '', ''],
PostTime => [6, 'date', 20, 20, 1, &get_date, ''],
PostedBy => [7, 'alpha', 30, 35, 1, 'Larry', ''],
Verified => [8, 'alpha', 0, 3, 1, 'Yes', 'Yes|No'],
UserID => [9, 'alpha', -2, 15, 0, '', '']
);

I would rather not remove the date format check that you mentioned earlier. It came in very handy when I was hand modifying the dates, the sub caught numerous typos.

I am going to dig in now and try your other suggestions. I will be back soon to let you know how it works out.

------------------
Larry "NgtCrwlr" Mingus
www.makeitsimple.com
Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
Question, I just noticed that I have

# Auth user field. This is the field position in the database used for storing
# the userid who owns the record. Set to -1 if not used.
$auth_user_field = 9;

I am wondering if I set that wrong and it should be 10 because the field definitions start at zero. Hmmm?


------------------
Larry "NgtCrwlr" Mingus
www.makeitsimple.com
Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
No, you have the $auth_user_field set correctly.

You definitely need to have the PostDate set to data type "date." I was just making sure. Smile

I just can't figure out why the date sorting isn't working. We've fixed the missing $ in the date_to_unix subroutine.

I'm stumped. I'm gonna have to ponder this a bit.

------------------
JPD





Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
I think I got your answer!

In sub get_date, instead of

$time = @_;

use

$time = @_[0];

Give 'er a try and let me know what happens.

------------------
JPD





Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
Ok I have some time to dig into this again. First a few questions. You suggest changing get_date to $time = @_[0]; My thought is, get date seems to work fine so I don't think the problems is there.

What seems to be happening is the time portion of our new date/time is getting lost.

What it looks like is, there is a missing conversion for time in our sub date_to_unix I will try to explain below.

In get time there is something being done to hours, min, sec. Maybe you could explain what is happening here.

($sec < 10) and ($sec = "0$sec");
($min < 10) and ($min = "0$min");
($hour < 10) and ($hour = "0$hour");

Don't we have to have something similar to reverse this in date_to_unix to get valid time data?

The current date_to_unix does some conversion to day and year but nothing is done to time, time is passed straight through

eval {
$day = int($day); $year = int($year) - 1900;
$time = timelocal($sec,$min,$hour,$day,$months{$mon},$year);
};

I am hoping that once I truly understand what is happening with date conversions that (I) will be able to convert these subs to handle 12hr formats. I have been paying attention to sites as I surf and it seems that 90% are not using military time. I am not trying to pass this off on you Carol. I think I can handle it, I already have a second sub that displays 12hr format with AM/PM and it works fine. I just need to understand what is wrong with our current search on date/time. I think we are getting close. Smile

------------------
Larry "NgtCrwlr" Mingus
www.makeitsimple.com

[This message has been edited by NgtCrwlr (edited May 16, 1999).]
Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
Maybe it wasn't your problem that needed the change in get_time. I know it was somebody's!

Regarding the

($sec < 10) and ($sec = "0$sec");
($min < 10) and ($min = "0$min");
($hour < 10) and ($hour = "0$hour");

All that does is format the time nicely so that you have "01:05:05" instead of "1:5:5." But Perl doesn't care about the zeros. It looks just at the numbers. One of the really nice things about Perl is that you don't have to define text and numbers differently like you to with a lot of other languages. If you are doing a computation, it will convert the text to numbers automatically.

Then again, maybe it would be good to have a couple of lines:

$sec = int($sec);
$min = int($min);
$hour = int($hour);

It can't hurt! If it helps, let me know. I'm learning this along with you. Smile

------------------
JPD





Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
Well, I figured out on my own that
($sec < 10) and ($sec = "0$sec");
adds a zero if seconds are less than 10.
So I would guess that a similar routine would be necessary to strip the zeros form seconds, minutes, and hours before passing them back as a unix time.

Am I correct?

------------------
Larry "NgtCrwlr" Mingus
www.makeitsimple.com
Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
We must have posted about the same time I just saw your post. This is really good because I am starting to get a better grip on Perl, all because of this date/time routine. This will for sure help me in debuging future problems.

I am approaching this problem one line at a time. I setup a page that I am running each line of the date-to-unix though so I can see and verify the output of each secton of the sub. This idea turned out to be a very good exercise in better undersanding Perl.

I will let you know what I find out.

BTW your one line addition to html_record
$rec{'Description'} =~ s/\n/<BR>/g;
worked like a charm! Now I have line feeds in my output for the description field. While I am thinking about it what do I add to that line to not remove spaces I am using spaces to indent the first line of each paragraph. Yikes he won't quit with the questions!

------------------
Larry "NgtCrwlr" Mingus
www.makeitsimple.com
Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
SUCCESS!

The Date/Time sort is working wonderful.

Unfortunately I cannot tell you exactly what made it work. Duh! It very well could have been a previous mistake that got corrected by accident through all of the trial and error.

The end result is, I have jumped up a level in my Perl understanding. No longer will I look at Unix dates with total bewilderment. Wink

I am going to paste the subs here just in case someone else needs date AND time sorting.

DON'T FORGET that you need both subroutines for this to work. Also, the format is (Month-Day-Year Hour:Minute:Second) and uses Military time. I am going to start work on a 12hr AM/PM format and see how that goes.

sub date_to_unix {
# --------------------------------------------------------
# This routine must take your date format and return the time a la UNIX time().
# Some things to be careful about..
# int your values just in case to remove spaces, etc.
# catch the fatal error timelocal will generate if you have a bad date..
# don't forget that the month is indexed from 0!
#
my ($date_and_time) = $_[0];
my (%months) = ("Jan" => 0, "Feb" => 1, "Mar" => 2, "Apr" => 3,
"May" => 4, "Jun" => 5, "Jul" => 6, "Aug" => 7,
"Sep" => 8, "Oct" => 9, "Nov" => 10,"Dec" => 11);
my ($date, $time) = split(/ /, $_[0]);
my ($mon, $day, $year) = split(/-/, $date);
my ($hour, $min, $sec) = split(/:/, $time);
unless ($mon and $day and $year) { return undef; }
unless (defined($months{$mon})) { return undef; }
use Time::Local;
eval {
$sec = int($sec);
$min = int($min);
$hour = int($hour);
$day = int($day);
$year = int($year) - 1900;

$time = timelocal($sec,$min,$hour,$day,$months{$mon},$year);
};

if ($@) { return undef;} # Could return 0 if you want.
return ($time);
}

********************************
sub get_date {

my ($time) = @_;
($time) | | ($time = time());
my ($sec, $min, $hour, $day, $mon, $year, $dweek, $dyear, $daylight) = localtime($time);
my (@months) = qw!Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec!;
($day < 10) and ($day = "0$day");
$year = $year + 1900;
($sec < 10) and ($sec = "0$sec");
($min < 10) and ($min = "0$min");
($hour < 10) and ($hour = "0$hour");

return "$months[$mon]-$day-$year $hour:$min:$sec";
}

You can still have a separate get_date and get_time if you rename them to something else. Just make sure that you keep the same format for dates. mmm-dd-yyyy

Thank you for all the help Carol. Now maybe I can help someone else, with my new (limited) Perl date knowledge.

------------------
Larry "NgtCrwlr" Mingus
www.makeitsimple.com

[This message has been edited by NgtCrwlr (edited May 17, 1999).]
Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
Wow! You have done all the things that make my participation here worthwhile. You have found (or at least fixed) your own error. You have learned a lot about how the language works. You have helped others by posting the subroutines. And you have offered to help as you can in the future. There couldn't be anything better for me than to read that.

Keeping the indenting is basically the same as keeping the carriage returns. Again, the spaces are there, but html doesn't show them.

After

$rec{'Description'} =~ s/\n/<BR>/g;

add

$rec{'Description'} =~ s/ /& nbsp;& nbsp;/g;

(In case it doesn't show up in the UBB page, that's 2 spaces after the s/ -- Also, take out the space between the & and the nbsp; I had to separate them so they would show up at all.)

What that will do is substitute two non-breaking spaces wherever there are two spaces in your field. If you wanted to indent by five spaces, you could put 5 spaces in the first part and 5 & nbsp; in the second part.

The structure for this is
Code:
$rec{'FieldName'} =~ s/[what you want replaced]/[what you want to replace it with/g;

The s part means "substitute" and the g part means "global" -- replace all instances. If you don't use the g, it will only replace the first one it finds.

Did you want me to work with you on the "am/pm" thing or did you want to try that yourself?



------------------
JPD





Quote Reply
Re: How to sort by DATE and TIME part 2 In reply to
Well, this is a win - win situation isn't it? Your happy, we’re happy, it just doesn't get much better. Wink

So, here is another one for you... hehe

Your last mod for putting the spaces back into my description field works 90%, it works on all paragraphs except the first line of the field. Hmmm

A bonus for me is that I use two spaces after sentences for better readability and this mod puts those back it too. I like that a lot. I usually indent five spaces so the mod converts those to four which is perfectly fine. Now I just need help figuring out why it doesn't work on the first line.

I was think about the a few possible catch 22's, I am going to experiment and see what the mod will do to non-standard paragraph formatting. Let's say I wanted to do a list or insert a Perl routine.

Being that this is a new problem, I think I will start a new topic so this doesn't get buried here.

Here is the new topic.

Keep original text formating in output.


------------------
Larry "NgtCrwlr" Mingus
www.makeitsimple.com