PDA

View Full Version : تبدیل تاریخ میلادی به شمسی



behz4d
شنبه 14 بهمن 1391, 18:09 عصر
با سلام،
من قبلا خیلی با کلاسها و توابع تبدل تاریخ میلادی به جلالی کار کرده بودم، اما امروز به یک مشکل جالبی برخوردم.
تاریخ امروز به میلادی:
2013/2/2
یک ماه بعد از این تاریخ به میلادی:
2013/3/2
تاریخ امروز به جلالی:
1391/11/14
یک ماه بعد از این تاریخ به جلالی:
1391/12/14

خب تا اینجای کار همه چیز درسته، من توی برنامه‌ای که نوشتم دارم تاریخها رو به میلادی در دیتابیس ذخیره میکنم و فقط هنگامی که بخوام به کاربر نشون بدم با یک تابع اونو به جلالی تبدیل میکنم...
اما مشکلی که پیش اومده اینه که وقتی 2013/3/2 رو به میلادی تبدیل میکنم، خروجیم میشه: 1391/12/12
درصورتیکه باید بشه 1391/12/14

با چند تا کلاس مختلف هم تست کردم نتیجه یکسان بود...
احتمالا باید دلیل دیگه‌ای داشته باشه، کسی میدونه؟

با تشکر

Tarragon
شنبه 14 بهمن 1391, 18:23 عصر
دلیلش ماه ها هستش!
ما ترتیب داریم ماه هامون هست 6 تا 31 و 5 تا 30 و یک 29 ( کبیسه رو حساب نکردم) اما در میلادی اینجوریه نام فرانسوی نام انگلیسی شمار روز
۱ ژانویه جَنیوری ۳۱
۲ فوریه فِبریوری ۲۸ یا ۲۹
۳ مارس مارچ ۳۱
۴ آوریل اپریل ۳۰
۵ مه مِی ۳۱
۶ ژوئن جون ۳۰
۷ ژوئیه جولای ۳۱
۸ اوت آگِست ۳۱
۹ سپتامبر سِپتِمبر ۳۰
۱۰ اکتبر آکتُبر ۳۱
۱۱ نوامبر ناوِمبر ۳۰
۱۲ دسامبر دیسِمبر ۳۱
دلیل تفاوتش اینه!

SadeghPro19
شنبه 14 بهمن 1391, 19:01 عصر
خب دوست عزیز از تابع time() استفاده کنید خیلی راحت و بدون دردسر هست و هر بلایی که بخواید می تونید سر تاریختون بیارید...

behz4d
شنبه 14 بهمن 1391, 19:02 عصر
amin@
ممنون از پاسختون
خب راه حل چیه؟! الان توی پروژم چیکار کنم که تاریخها دقیق در بیاد؟
کاربر داره واسه یک ماه یک چیزی رو میخره، اینطوری دوروز زودتر از موعد دسترسیش بسته میشه به امکانات...

sadegh@
با time چجوری تاریخ که به صورت datetime در دیتابیس ذخیره شده رو یک ماه بدش رو محاسبه کنم؟

ممنون

SadeghPro19
شنبه 14 بهمن 1391, 19:13 عصر
خب چندین راه دارین یکی این که به ثانیه یک ماه رو محاسبه کنید به این صورت : 60*60*24*30
راه دوم اینه که تایم رو بدین به date یا تابع جلالی jdate و به اون یک ماه اضافه کنید و نمایش بدین یا اگه میخواهید در دیتابیس ثبت کنید اون رو با تابع strtotime تبدیل کنید به تایم و اون رو در دیتابیس ذخیره کنید..

behz4d
شنبه 14 بهمن 1391, 19:36 عصر
ممنون بابت پاسختون
من بالا به اشتباه گفتم که کاربران 2 روز زودتر از موعد حساب کاربریشون بسته میشه، چون همه چیز داره به میلادی توی دیتابیس ذخیره میشه و اون تاریخ هم درسته یعنی 2013/3/2 هستش...
الان مشکل من تبدیل 2013-03-02 15:41:50 هست به 1391/12/14
میتونید با نمونه کد راهنمایی کنید؟ من هرکاری میکنم میشه 1391/12/12 که غلطه...

tehro0n
شنبه 14 بهمن 1391, 19:50 عصر
چرا انقدر سخت میگیری، حالا که به time ذخیره نکردی به جای اینکه برای مشتری یک ماه میلادی رو اضافه کنی بیا و 30 روز اضافه کن، تابع date که خودش ماه میلادی رو می تونه +30 روز کنه، اون وقت هم که ذخیره کنی برای تبدیلش تاریخ 30 روز بعد جلالی رو نمایش میدی..
فقط به مشتری بگو 30 روز که نیمه اول 31 روزه شد به مشکل نخوری، یا اینکه خودت دستی و یا با تابعی بگی هر ماه چند روز باشه

اینم کد 30 روز جلوتر

mktime(0, 0, 0, date("m") , date("d")+30, date("Y"));

behz4d
شنبه 14 بهمن 1391, 21:59 عصر
tehro0n@
ممنون بابت پاسخ، اما قضیه سخت گرفتن نیست! با این راه حل شما درست شد مشکلم، ممنون...
اما هنوز یه سوال واسم باقی مونده، اونم اینکه فرض کنیم من یک تاریخ دارم: 3-2-2013، این تاریخ رو بخوام مستقیم به شمسی تبدیل کنم داستان چه‌جوریه؟

ممنون
(P.S: از مباحث زمان توی PHP متنفرم!)

MMSHFE
شنبه 14 بهمن 1391, 23:53 عصر
دوست گرامی، 2013/3/2 واقعاً میشه 1391/12/12 شما چرا اصرار دارین بشه 14 ؟ ماه فوریه امسال 28 روزه است! در حالی که بهمن 30 روزه است. شما اگه میخواین درست کار بشه، باید 30 روز به تاریخ شروع ثبت نام اضافه کنید نه 1 ماه چون ماه ممکنه 28، 29، 30 یا 31 روزه باشه درحالی که شما دقیقاً 30 روز لازم دارین.

MMSHFE
یک شنبه 15 بهمن 1391, 00:42 صبح
(P.S: از مباحث زمان توی PHP متنفرم!)
چرا؟ به این خوبی و باحالی؟ یه timestamp داریم که توی همه کشورها و کدها ثابته. اینکه ماه فوریه توی سالهای کبیسه 28 روزه است به PHP چه ربطی داره؟

tehro0n
یک شنبه 15 بهمن 1391, 00:43 صبح
اما هنوز یه سوال واسم باقی مونده، اونم اینکه فرض کنیم من یک تاریخ دارم: 3-2-2013، این تاریخ رو بخوام مستقیم به شمسی تبدیل کنم داستان چه‌جوریه؟


اون رو که گفته بودی چندین کلاس داری و تست کردی! اگه می خوای یه جوری کاری کنی که برج 2 بشه 30 روز باور کن نمیشه :لبخند:
اینم یه تابع برای تبدیل مستقیم میلادی به شمسی


<?php
function gregorian_to_jalali($g_y,$g_m,$g_d,$mod=''){
$d_4=$g_y%4;
$g_a=array(0,0,31,59,90,120,151,181,212,243,273,30 4,334);
$doy_g=$g_a[(int)$g_m]+$g_d;
if($d_4==0 and $g_m>2)$doy_g++;
$d_33=(int)((($g_y-16)%132)*.0305);
$a=($d_33==3 or $d_33<($d_4-1) or $d_4==0)?286:287;
$b=(($d_33==1 or $d_33==2) and ($d_33==$d_4 or $d_4==1))?78:(($d_33==3 and $d_4==0)?80:79);
if((int)(($g_y-10)/63)==30){$a--;$b++;}
if($doy_g>$b){
$jy=$g_y-621; $doy_j=$doy_g-$b;
}else{
$jy=$g_y-622; $doy_j=$doy_g+$a;
}
if($doy_j<187){
$jm=(int)(($doy_j-1)/31); $jd=$doy_j-(31*$jm++);
}else{
$jm=(int)(($doy_j-187)/30); $jd=$doy_j-186-($jm*30); $jm+=7;
}
return($mod=='')?array($jy,$jm,$jd):$jy.$mod.$jm.$ mod.$jd;
}

list($JY, $JM, $JD) = explode("-", "2013-2-3");
echo gregorian_to_jalali($JY,$JM,$JD,$mod='/');
?>

behz4d
یک شنبه 15 بهمن 1391, 11:18 صبح
من تازه فهمیدم مشکل از کجاست :لبخند: ممنون از دوستان!