Perl w3ctime function

Disclaimer:
The use of this code is at your own risk.

Description:
This subroutine returns a scalar in the format of the w3ctime.
w3ctime format is used in xml sitemaps from google

Purpose:
I was missing a function in Perl that did this.
So I wrote my own
I needed it for a Perl program that writes XML site maps
See https://www.comweb.nl/perl/makeSitemapXML/makeSitemapXML.html
I hope did not reinvent the wheel.

Performance:
Some testing done.
Simple readable source code I hope.

Donation:
If you want to support my work, thanks

Source Code description:
Use the source luke
Think that is easy

Download:
https://www.comweb.nl/perl/w3ctime/w3ctime.zip

  
1:	#!/usr/bin/perl
2:	
3:	   # this subroutine changes a number to the w3c timeformat
4:	   # the number is the time in seconds passed after 1 jan 1970
5:	   # same as gmtime from perl does.
6:	   # But this sub returns the W3C time format.
7:	   
8:	   # (c) RJHM van den Bergh, Comweb Netherlands.
9:	   # Please report bugs and sugestions to sales2@comweb.nl
10:	   # version 1.0 betta
11:	   
12:	   # No liability accepted
13:	   # Free to use and distribute
14:	   # please keep my name in the source code       
15:	
16:	   use strict;
17:	   use warnings;
18:	   use POSIX;
19:	   
20:	# For testing
21:	print "\n";
22:	print "Testing w3ctime function\n";
23:	print "See https://www.w3.org/TR/NOTE-datetime \n";
24:	print "\n";
25:	
26:	print "w3ctime(0)= ".&w3ctime("0")."\n";
27:	print "gmtime(0) = ".gmtime(0)."\n";
28:	print "\n";
29:	
30:	print "w3ctime(86400)= ".&w3ctime("86400")."\n";
31:	print "gmtime(86400) = ".gmtime(86400)."\n";
32:	print "\n";
33:	
34:	print "w3ctime(1549658691)= ".&w3ctime("1549658691")."\n";
35:	print "gmtime(1549658691) = ".gmtime(1549658691)."\n";
36:	print "\n";
37:	
38:	sub w3ctime()
39:	{
40:	    my $time_passed_since_epoch=shift;  #  time in seconds since 1 jan 1970 00:00:00
41:	    # initialize some variables
42:	    my $year=1970;
43:	    my $isLeapYear=0;
44:	    my $leapYearInSeconds=366*24*60*60;
45:	    my $yearInSeconds    =365*24*60*60;
46:	    my $start_counter=0;
47:	    
48:	    
49:	    while( $start_counter<=$time_passed_since_epoch)
50:	    {
51:	      #determine if it is a leap year      
52:	      if (($year % 4)==0   ) { $isLeapYear=1; } else { $isLeapYear=0; }
53:	      if (($year % 100)==0 ) { $isLeapYear=0; } # exception
54:	      if (($year % 400)==0 ) { $isLeapYear=1; } # exception      
55:	      
56:	      # add seconds of that year to the start counter
57:	      if( $isLeapYear ) 
58:	      {
59:	         $start_counter+=$leapYearInSeconds; 
60:	      } else
61:	      {
62:	         $start_counter+=$yearInSeconds;
63:	      }      
64:	      $year++;      
65:	    }
66:	    # $tart passed $time_passed
67:	    $year--;
68:	    if( $isLeapYear ) 
69:	    {
70:	      $start_counter-=$leapYearInSeconds; 
71:	    } else
72:	    {
73:	      $start_counter-=$yearInSeconds;
74:	    }
75:	    
76:	    my $month=0;
77:	    # can add jan 31 days?
78:	    if ( ($start_counter+31*24*60*60)<=$time_passed_since_epoch )
79:	    {
80:	       $start_counter+=31*24*60*60;  
81:	       $month++;
82:	
83:	       # can add februari?
84:	       my $februariDays=28;
85:	       if ($isLeapYear) { $februariDays=29;}
86:	       if ( ($start_counter+$februariDays*24*60*60)<=$time_passed_since_epoch )
87:	       {
88:	          $start_counter+=$februariDays*24*60*60;  
89:	          $month++;
90:	       
91:	          # can add march?
92:	          if ( ($start_counter+31*24*60*60)<=$time_passed_since_epoch )
93:	          {
94:	             $start_counter+=31*24*60*60;  
95:	             $month++;
96:	       
97:	             # can add april?
98:	             if ( ($start_counter+30*24*60*60)<=$time_passed_since_epoch )
99:	             {
100:	                $start_counter+=30*24*60*60;  
101:	                $month++;
102:	
103:	                # can add may?
104:	                if ( ($start_counter+31*24*60*60)<=$time_passed_since_epoch )
105:	                {
106:	                   $start_counter+=31*24*60*60;  
107:	                   $month++;
108:	                
109:	                   # can add june?
110:	                   if ( ($start_counter+30*24*60*60)<=$time_passed_since_epoch )
111:	                   {
112:	                      $start_counter+=30*24*60*60;  
113:	                      $month++;
114:	
115:	                      # can add july?
116:	                      if ( ($start_counter+31*24*60*60)<=$time_passed_since_epoch )
117:	                      {
118:	                         $start_counter+=31*24*60*60;  
119:	                         $month++;
120:	
121:	                         # can add august?
122:	                         if ( ($start_counter+31*24*60*60)<=$time_passed_since_epoch )
123:	                         {
124:	                            $start_counter+=31*24*60*60;  
125:	                            $month++;
126:	
127:	                            # can add september?
128:	                            if ( ($start_counter+30*24*60*60)<=$time_passed_since_epoch )
129:	                            {
130:	                               $start_counter+=30*24*60*60;  
131:	                               $month++;
132:	
133:	                               # can add oktober?
134:	                               if ( ($start_counter+31*24*60*60)<=$time_passed_since_epoch )
135:	                               {
136:	                                  $start_counter+=31*24*60*60;  
137:	                                  $month++;
138:	                               
139:	                                  # can add november?
140:	                                  if ( ($start_counter+30*24*60*60)<=$time_passed_since_epoch )
141:	                                  {
142:	                                     $start_counter+=30*24*60*60;  
143:	                                     $month++;
144:	
145:	                                     # can add december?
146:	                                     if ( ($start_counter+31*24*60*60)<=$time_passed_since_epoch )
147:	                                     {
148:	                                        $start_counter+=31*24*60*60;  
149:	                                        $month++;
150:	
151:	                                        # if it comes here then something not correct
152:	                                        # should not be possible to add full decembre month
153:	                                        # because then it is next year
154:	                                        die "Oops it shouldn't get here";
155:	                                                                                                                     
156:	                                     }
157:	                                  }
158:	                               }
159:	                            }
160:	                         }
161:	                      }
162:	                   }
163:	                }
164:	             }
165:	          }
166:	       }
167:	    }
168:	    
169:	    # calculate days in the month lowest day = 0
170:	    my $days=floor(($time_passed_since_epoch-$start_counter)/(24*60*60));
171:	    $start_counter+=($days*24*60*60);
172:	    if (($days+1)>31) { die "Oops days can't be bigger than 31.";}
173:	    
174:	    #calculate hours lowest = 0
175:	    my $hours=floor(($time_passed_since_epoch-$start_counter)/(60*60));
176:	    $start_counter+=($hours*60*60);
177:	    if ($hours>=24) { die "Oops hours must be less than 24.";}
178:	    
179:	    # calculate minutes lowest = 0
180:	    my $minutes=floor(($time_passed_since_epoch-$start_counter)/(60));
181:	    $start_counter+=($minutes*60);
182:	    if ($minutes>=60) { die "Oops minutes must be less than 60.";}
183:	
184:	    my $seconds=floor($time_passed_since_epoch-$start_counter);
185:	    if ($seconds>=60) { die "Oops seconds must be less than 60.";}
186:	    
187:	    # putting everything in the right format
188:	    $year  = sprintf("%04d", $year); 
189:	    $month = sprintf("%02d", $month+1);
190:	    $days  = sprintf("%02d", $days+1); 
191:	    $hours   = sprintf("%02d", $hours);  
192:	    $minutes = sprintf("%02d", $minutes); 
193:	    $seconds = sprintf("%02d", $seconds);
194:	    
195:	    my $w3cTimeString="$year-".($month)."-".($days)."T".$hours.":".$minutes.":".$seconds."Z";
196:	    return $w3cTimeString; 
197:	}