Gossamer Forum
Home : Products : DBMan : Customization :

re: autoincrementing dates

Quote Reply
re: autoincrementing dates
The thread was very interesting to me , as I am currently doing a booking system.

I need to have one record for each day in the year, and I did the ID incrementing from 1999-001 as shown in that thread. ( I must have 1999 and 2000 in place of 99 and 00)And I changed the date to Unix, and its OK.
Now I need the ID to change to 2000-001 when we hit 1999-366.
As I am not very good at Perl, I would appreciate some suggestion how to do this.

Furthermore I have a field called Date, and I would really like to have the date corresponding to the ID written automatically in that field. So that the ID-field shows 1999-031 and the date 31-Jan-1999 is written in the date field.
Any ideas?



[This message has been edited by poulR (edited January 28, 1999).]
Quote Reply
Re: re: autoincrementing dates In reply to
Thank you for explaining the steps in the code.
I used some of it already. But as I am working with a booking system I must have records 1 year ahead, thus can not compare to &get_date.

I am trying something like this:
-------------
sub get_defaults {
# --------------------------------------------------------
# Returns a hash of the defaults used for a new record.

my (%default);

foreach $field (keys %db_defaults) {
$default{$field} = $db_defaults{$field};
}

if ($db_key_track) {
open (ID, "<$db_id_file_name") or &cgierr("error in get_defaults. unable to open id file: $db_id_file_name.\nReason: $!");
if ($db_use_flock) { flock(ID, 1); }
need to define $prefix?
$count = substr(<ID>,5)+1;
($count < 100 and 9 < $count ) and ($count = "0$count");
($count < 10) and ($count = "00$count");
if (364 < $count) {$count="001" and $prefix=2000};
$default{$db_key} = "$prefix-$count"; # Get next ID number
close ID;
}
return %default;
}
-----------
I need to set $prefix to the first 4 characters of the <ID> for the start?
($prefix, $count) = unpack("A4 x1 A*", <ID> );
didnt seem to work for me
Quote Reply
Re: re: autoincrementing dates In reply to
Dear poulR,

I am glad that the thread I started has been of help to people. I have a similar ID and here is how I solve the 2000 switch:

Code:
if ($db_key_track) {
open (ID, "<$db_id_file_name") or &cgierr("error in get_defaults. unable to open id file: $db_id_file_name.\nReason: $!");
if ($db_use_flock) { flock(ID, 1); }
($prefix, $count) = unpack("A2 x1 A*", <ID> );
$count=$count+3;
$test = substr(&get_date,-2);
if ($test ne $prefix) {$count="100" and $prefix=$test};
$default{$db_key} = "$prefix-$count"; # Get next ID number
close ID;
}

This code is found at the end of the get_defaults subrouting in db.cgi. Note that the ID is stored in my case as YY-###. The unpack function splits it into $prefix = YY and $count=###. If you are new to PERL the "A2 x1 A*" argument splits the ID in two strings, the first containing the first two bytes, then skips one (the hyphen) then the second string consists of the remaining bytes.

My ID's increment by three, thus $count= $count+3.

I then set the $test variable to the last two digits of the year returned by the get_date subroutine. This time I used substr which is similar to unpack. (&get_date,-2) returns the last two bytes of &get_date.

Then I compare the $test year and the $prefix year. If they aren't the same the year has changed since we added the last record and I set $prefix = $test (the new year) and rest the counter to 100. Otherwise the ID simply is $prefix-$count.

Hope this helps. Since you have one record for each day in the year your code could be simpler: simply reset $prefix and $count if ($count = 366). You can figure out how you want to do it!

I think the following should work for your date field. Multiply the $count number, eg. 236 is the 236th day, by 24x60x60 to turn it into UNIX seconds. Then turn this into the date with &get_date but change it to return only the $day-$month. Then add the $prefix year to the end. There are probably a lot more simple ways to do this too. It's just an idea. It's probably better to write a short PERL script to populate your database array if I understand what you are trying to do.

Sincerely,
Lauren Stegman
Quote Reply
Re: re: autoincrementing dates In reply to
Well I came up with this by now , and it does what i wanted:

---------
sub get_defaults {
# --------------------------------------------------------
# Returns a hash of the defaults used for a new record.

my (%default);

foreach $field (keys %db_defaults) {
$default{$field} = $db_defaults{$field};
}

if ($db_key_track) {
open (ID, "<$db_id_file_name") or &cgierr("error in get_defaults. unable to open id file: $db_id_file_name.\nReason: $!");
if ($db_use_flock) { flock(ID, 1); }
($prefix, $count) = unpack("A4 x1 A*", <ID> );
$count = $count+1;
($count < 100 and 9 < $count) and ($count = "0$count");
($count < 10) and ($count = "00$count");
if (364 < $count) {$count="001" and $prefix="2000"};
$default{$db_key} = "$prefix-$count"; # Get next ID number
close ID;
}
return %default;
}
----------
counts from 1999-001 and changes to 2000-001 from 1999-365, and I I put a Validation of ID in the cfg-file, as it is really important that this format is right through-out:

-----
%db_def = (
ID => [0, 'numer', 5, 8, 1, '', '\d{4}-[0-3]\d{2}'],

------
maybe better '[1-2]\d{3}-[0-3]\d{2}'

I am sure this can be done a lot nicer, but I know practically nothing about perl.

I do want my date field to refect the real date format 30-jan-1999 from the ID. So that if ID is 1999-030 , the string 30-jan-1999 is written in another field.

I can do something like:

------
sub get_datcvt {
# --------------------------------------------------------
# Convert ID-count to datestring
#

if ($count > 334) { $md = dec and $udag = $count - 334 ; }
elsif ($count > 304) { $md = nov and $udag = $count - 304 ; }
elsif ($count > 273) { $md = okt and $udag = $count - 273 ; }
elsif ($count > 243) { $md = sep and $udag = $count - 243 ; }
elsif ($count > 212) { $md = aug and $udag = $count - 212 ; }
elsif ($count > 181) { $md = jul and $udag = $count - 181 ; }
elsif ($count > 151) { $md = jun and $udag = $count - 151 ; }
elsif ($count > 120) { $md = maj and $udag = $count - 120 ; }
elsif ($count > 90) { $md = apr and $udag = $count - 90 ; }
elsif ($count > 59) { $md = mar and $udag = $count - 59 ; }
elsif ($count > 31) { $md = feb and $udag = $count - 31 ; }
else ($count > 0) { $md = jan and $udag = $count ; }

return "$udag-$md-$prefix";
}

But how do I get in the code, and will it work?

I again am sure it can be done in a much more elegant way?