How to calculate the seconds till the end of the month in Perl: How to make people disconnect at a given time: Keywords: Lucent US Robotics Cisco NAS Radiator Radius: Ok, I've lied slightly, this is actually to count how many seconds till the current minute and second in the last hour of the month. The reasoning will become clear when you read the code: We use this code to set the session times on dial up connections to our ISP. It's in the best interests of our billing system if people are disconnected before the end of the month. We'd though about ways of telling the Network Access Servers (NAS's) to disconnect everyone before the end of the month, but these methods were clunky, and didnt help with our rented pops. So we realised that when a user connects, and radiator gives them their session details, they will be given a connection duration, this would normaly be a set number of hours for normal customers, or unlimited for perms. With this script we instead give them a number of seconds that will give them their normal time, or the time to just before the end of the month, if that is closer. But it doesnt do it at a static time, so that we dont have thousands of people disconnect at once, which would do bad things to the billing system. Drop me a line if you found this code useful. I'd love to hear from you: danielt@-SpamMeNot-lexicon.net #!/usr/bin/perl # This script will return an ASCII representation of the number of seconds # till 'this time' (ie current minute and second) in the last hour of the month. # # It is to be used to generate session timesouts that will see customers # diconnected slightly before the end of the month, for billing reasons, but no # all disconnect at the same time for technical reasons. # # The script does take into account: # daylight savings; # year changes; # connections in the last hour of a month; # # The script doesn't take into account: # Being run from a different time zone to the radius server; # Non 32bit processors/Leap Seconds/Times after 2038; # # # # Author: D Trembath 11/09/01 # Update: Daniel 5/12/02 Spelling mistakes; Notes # # Variable naming: # 'n' prefix is for 'now' 'f' is for 'future' # Daylight Savings: # '0' is not DLS '1' is DLS # $anHour = (60 * 60); # Use time libraries (standard perl) use Time::Local; # get a timestamp $nTime = time; # get usable variables from this time stamp with 'localtime' ($nSec,$nMin,$nHour,$nMDay,$nMon,$nYear,$nWday,$nYday,$nisDst) = localtime($nTi; # see if we're in daylight savings time now $nTimeDLS = $nisDst; # check to see that its not the last month of the year. # if so, add one to year if($nMon == 12) { $nYear = $nYear + 1; } # check to see if its already the last hour of the month. # if so, calculate one hour from the end of NEXT month if($nHour >= 22) { $nMon = $nMon + 2; } else { $nMon = $nMon + 1; } # generate a new time stamp of 'This Second', 'this Minute', in the first hour ) # of the first day ("1") of next month $fTime = timelocal($nSec,$nMin,"0","1",$nMon,$nYear); # subtract an hour to go back into last month $fTime = $fTime - $anHour; # convert this time stamp to usefull information ($fSec,$fMin,$fHour,$fMDay,$fMon,$fYear,$fWday,$fYday,$fisDst) = localtime($fTi; # see if it will be daylight savings time then $fTimeDLS = $fisDst; # adjust time forward or backward for daylight savings if($nTimeDLS == 0 && $fTimeDLS == 1) { $fTime = $fTime + $anHour} elsif($nTimeDLS == 1 && fTimeDLS == 0) { $fTime = $fTime - $anHour} #Un-comment these for testing purposes #print("Now: $nTime\n"); #print("DLS?: $nTimeDLS\n"); #print("Then: $fTime\n"); #print("DLS?: $fTimeDLS\n"); $timeLeft = $fTime - $nTime; #print("Seconds: $timeLeft\n"); print("$timeLeft");