package JalaliDate; # Copyright (C) 2002,2003 Hamid Hashemi # # Date Converter Functions Original PHP version is: # Copyright (C) 2001 Roozbeh Pournader # Copyright (C) 2001 Mohammad Toossi # and can be found at the World Wide Web address: # http://www.farsiweb.info/jalali/jalali.phps # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You can receive a copy of GNU Lesser General Public License at the # World Wide Web address . # # For licensing issues, contact The FarsiWeb Project Group, Computing # Center, Sharif University of Technology, PO Box 11365-8515, Tehran, Iran, # or at the email address , # and Hamid Hashemi . # ########################################################################### ########################################################################### use strict; use warnings; use POSIX qw( strftime ); BEGIN { use Exporter (); our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); # set the version for version checking $VERSION = 0.01; @ISA = qw(Exporter); @EXPORT = qw(&farsi_number &gregorian_to_jalali &g2jstrftime &jalali_to_gregorian); %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ], } our @EXPORT_OK; my @g_days_in_month = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); my @j_days_in_month = (31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29); my $div = sub { return int( $_[0] / $_[1] ); }; sub farsi_number($) # ( @_[0] = String contains english numbers to covert to farsi numbers ) { my %table; $table{"\x30"}="\xDB\xB0"; # Persian 0 $table{"\x31"}="\xDB\xB1"; # Persian 1 $table{"\x32"}="\xDB\xB2"; # Persian 2 $table{"\x33"}="\xDB\xB3"; # Persian 3 $table{"\x34"}="\xDB\xB4"; # Persian 4 $table{"\x35"}="\xDB\xB5"; # Persian 5 $table{"\x36"}="\xDB\xB6"; # Persian 6 $table{"\x37"}="\xDB\xB7"; # Persian 7 $table{"\x38"}="\xDB\xB8"; # Persian 8 $table{"\x39"}="\xDB\xB9"; # Persian 9 my $strout = ''; my $char = 0; foreach (split //,$_[0]) { if ( $table{$_} and $char == 0 ) { $strout .= $table{$_}; } else { $strout .= $_; $char = 1 if ( $_ eq '&' ); $char = 0 if ( $_ eq ';' ); } } return $strout; } sub gregorian_to_jalali($$$) # ( @_[0] = Gregorian_Year , @_[1] = Gregorian_Month , @_[2] = Gregorian_Day ) { my $i; my $gy = $_[0]-1600; my $gm = $_[1]-1; my $gd = $_[2]-1; my $g_day_no = 365*$gy+&$div($gy+3,4)-&$div($gy+99,100)+&$div($gy+399,400); for ($i=0; $i < $gm; ++$i) { $g_day_no += $g_days_in_month[$i]; } ++$g_day_no if ($gm>1 && (($gy%4==0 && $gy%100!=0) || ($gy%400==0))); $g_day_no += $gd; my $j_day_no = $g_day_no-79; my $j_np = &$div($j_day_no, 12053); # 12053 = 365*33 + 32/4 $j_day_no %= 12053; my $jy = 979+33*$j_np+4*&$div($j_day_no,1461); # 1461 = 365*4 + 4/4 $j_day_no %= 1461; if ($j_day_no >= 366) { $jy += &$div($j_day_no-1, 365); $j_day_no = ($j_day_no-1)%365; } for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i) { $j_day_no -= $j_days_in_month[$i]; } my $jm = $i+1; my $jd = $j_day_no+1; return ( $jy, $jm, $jd ); } sub g2jstrftime($$) # just Like strftime = ( @_[0] = pattern, @_[1] = timestamp ) { my $pattern = $_[0]; my $g_y = substr($_[1],0,4); my $g_m = substr($_[1],4,2); my $g_d = substr($_[1],6,2); my $hour_24 = substr($_[1],8,2); my $hour_12 = $hour_24%12; my $min = substr($_[1],10,2); my $sec = substr($_[1],12,2); my $g_d_s = strftime ("%a",0,0,0,$g_d,$g_m-1,$g_y-1900); my $t_s = 'صبح'; $t_s = 'بعدازظهر' if ( $hour_24 >= 12 ); my ($j_y, $j_m, $j_d) = gregorian_to_jalali ($g_y, $g_m, $g_d); my ($j_d_s, $j_d_i); if ( $g_d_s eq 'Sat' ) { ($j_d_s, $j_d_i) = ('شنبه', 'شنبه') } elsif ( $g_d_s eq 'Sun' ) { ($j_d_s, $j_d_i) = ('یکشنبه', '1 یکشنبه') } elsif ( $g_d_s eq 'Mon' ) { ($j_d_s, $j_d_i) = ('دوشنبه', '2 دوشنبه') } elsif ( $g_d_s eq 'Tue' ) { ($j_d_s, $j_d_i) = ('سه شنبه', '3 سه شنبه') } elsif ( $g_d_s eq 'Wed' ) { ($j_d_s, $j_d_i) = ('چهارشنبه', '4 چهارشنبه') } elsif ( $g_d_s eq 'Thu' ) { ($j_d_s, $j_d_i) = ('پنجشنبه', '5 پنجشنبه') } elsif ( $g_d_s eq 'Fri' ) { ($j_d_s, $j_d_i) = ('جمعه', 'جمعه') } my $j_m_s; if ( $j_m eq '1' ) { $j_m_s = 'فروردین' } elsif ( $j_m eq '2' ) { $j_m_s = 'اردیبهشت' } elsif ( $j_m eq '3' ) { $j_m_s = 'خرداد' } elsif ( $j_m eq '4' ) { $j_m_s = 'تیر' } elsif ( $j_m eq '5' ) { $j_m_s = 'مرداد' } elsif ( $j_m eq '6' ) { $j_m_s = 'شهریور' } elsif ( $j_m eq '7' ) { $j_m_s = 'مهر' } elsif ( $j_m eq '8' ) { $j_m_s = 'آبان' } elsif ( $j_m eq '9' ) { $j_m_s = 'آذر' } elsif ( $j_m eq '10' ) { $j_m_s = 'دی' } elsif ( $j_m eq '11' ) { $j_m_s = 'بهمن' } elsif ( $j_m eq '12' ) { $j_m_s = 'اسفند' } my $j_y_s = substr ($j_y,2,2); my $j_m_i = $j_m_s."ماه"; $pattern =~ s/\%H/$hour_24/g; $pattern =~ s/\%h/$hour_12/g; $pattern =~ s/\%m/$min/g; $pattern =~ s/\%s/$sec/g; $pattern =~ s/\%Y/$j_y/g; $pattern =~ s/\%t/$t_s/g; $pattern =~ s/\%y/$j_y_s/g; $pattern =~ s/\%M/$j_m/g; $pattern =~ s/\%b/$j_m_s/g; $pattern =~ s/\%B/$j_m_i/g; $pattern =~ s/\%d/$j_d/g; $pattern =~ s/\%a/$j_d_i/g; $pattern =~ s/\%A/$j_d_s/g; return $pattern; } sub jalali_to_gregorian($$$) # ( @_[0] = Jalali_Year , @_[1] = Jalali_Month , @_[2] = Jalali_Day ) { my $i; my $jy = $_[0]-979; my $jm = $_[1]-1; my $jd = $_[2]-1; my $j_day_no = 365*$jy + &$div($jy, 33)*8 + &$div($jy%33+3, 4); for ($i=0; $i < $jm; ++$i) { $j_day_no += $j_days_in_month[$i]; } $j_day_no += $jd; my $g_day_no = $j_day_no+79; my $gy = 1600 + 400*&$div($g_day_no, 146097); # 146097 = 365*400 + 400/4 - 400/100 + 400/400 $g_day_no = $g_day_no % 146097; my $leap = 1; if ($g_day_no >= 36525) # 36525 = 365*100 + 100/4 { $g_day_no--; $gy += 100*&$div($g_day_no, 36524); # 36524 = 365*100 + 100/4 - 100/100 $g_day_no = $g_day_no % 36524; if ($g_day_no >= 365) { $g_day_no++; } else { $leap = 0; } } $gy += 4*&$div($g_day_no, 1461); # 1461 = 365*4 + 4/4 $g_day_no %= 1461; if ($g_day_no >= 366) { $leap = 0; $g_day_no--; $gy += &$div($g_day_no, 365); $g_day_no = $g_day_no % 365; } for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++) { $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap); } my $gm = $i+1; my $gd = $g_day_no+1; return ($gy, $gm, $gd); } END { } 1;