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: }