آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
مشکل عدم دسترسی خریداران پیشین به برخی آموزش ها برطرف شد
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

الگوریتم تاریخ جلالی ( آموزش )

سهرابیان  7 سال پیش  7 سال پیش
+11 0

الگوریتم تبدیل تاریخ میلادی به تاریخ شمسی :

1- برای نوشتن الگوریتم به اختلاف روز های میان اولین روز سال میلادی ( 1 ژانویه ) و اولین روز سال شمسی ( 20 مارس ) نیاز داریم که برابر با "79" می باشد . 

2- در این مرحله باید تشخیص دهیم که سال میلادی کبیسه است یا خیر . برای اینکار باید سال میلادی داده شده را بر 4 تقسیم کنیم ، اگر بخشپذیر بود ( باقیمانده برابر صفر ) سال کبیسه است در غیر اینصورت سال میلادی کبیسه نیست . 

3- با توجه به کبیسه بودن یا کبیسه نبودن سال مشخص می کنیم که در کدامین روز سال میلادی قرار داریم ، که در اینصورت با دو حالت روبرو خواهیم شد : 

 1-3- سال کبیسه باشد :

1-1-3- روزی که در آن قرار داریم از 79 بیشتر باشد : 

به این معنی است که در ماههای بعد از فروردین قرار داریم . حال باید مشخص کنیم که در 6 ماه اول سال شمسی قرار داریم یا در 6 ماه دوم سال قرار داریم . برای اینکار ابتدا " 79 " روز از تعداد روز ها کم می کنیم تا در اول فروردین ماه قرار بگیریم . اگر تعداد روز های بدست آمده از  " 186  " ( 31 * 6 ) کمتر باشد یعنی در 6 ماه اول سال شمسی قرار داریم ، در غیر اینصورت در 6 ماه دوم قرار داریم .                              

1-1-1-3- اگر در 6 ماه اول سال قرار گرفته باشیم ( dates <= 186 ) : 

تعداد روزها را بر " 31 " تقسیم می کنیم ( چرا بر 31 تقسیم کنیم ؟ به این دلیل که در 6 ماه اول سال شمسی قرار داریم . ) ، اگر باقیمانده این تقسیم صفر شد ، خارج قسمت تقسیم برابر با ماه شمسی می شود و روز شمسی برابر با 31 می شود . در غیر اینصورت اگر باقیمانده صفر نشود ماه شمسی برابر با خارج قسمت به اضافه ی یک می شود و روز شمسی همان باقیمانده است .                                                                                        

2-1-1-3- اگر در 6 ماه دوم سال قرار گرفته باشیم : 

" 186 " روز از تعداد روز ها کم می کنیم و آن را بر " 30 " تقسیم می کنیم ( چرا بر 30 تقسیم می کنیم ؟ چون در 6 ماه دوم سال قرار گرفته ایم  و ماه ها 30 روزه می باشند . ) . اگر باقیمانده این تقسیم صفر شد ، خارج قسمت تقسیم به اضافه " 6 " و برابر ماه شمسی قرار خواهد گرفت و روز شمسی برابر  با  30 می شود . اگر باقیمانده صفر نشود ماه شمسی برابر با خارج قسمت به اضافه " 7 " می شود و روز شمسی همان باقیمانده است و در نهایت سال شمسی از تفاضل سال میلادی با " 621 "  بدست می آید .                                                                                                               

چرا برای بدست آوردن سال شمسی ، سال میلادی را از   621  کم کردیم ؟  همان طور که در بالا ( 3-1-1 ) ذکر کردیم ، یعنی روز مورد نظر بین اول فروردین تا 11 دی می باشد . 

2-1-3- روزی که در آن قرار داریم کمتر از " 79 " است :                      

به این معنی است که در روزهای بین اولین روز سال میلادی تا اولین روز سال شمسی ( دی ، بهمن ، اسفند ) قرار داریم . اختلاف روز بین اولین روز سال میلادی داده شده و اولین روز دی ماه در سال شمسی را در نظر می گیریم که این اختلاف برای سال کبیسه  " 11 " و برای سال غیر کبیسه  " 10 " می باشد .        

تــوجــه : در این الگوریتم برای مشخص کردن این اختلاف باید سال قبل از سال داده شده را در نظر بگیریم ، به این دلیل که سال قبل بر روی اولین روز سال میلادی تاثیر می گزارد .                    

در نهایت اختلاف تاریخ بدست آمده را با تعداد روز ها جمع می کنیم و آن را بر " 30 "  تقسیم می کنیم ( 3 ماه آخر سال شمسی 30 روزه است . ) ، اگر باقیمانده این تقسیم صفر شود ، خارج قسمت تقسیم به اضافه ی " 9 " برابر  با ماه برابر با خارج قسمت به اضافه " 10 " می شود و روز شمسی همان باقیمانده است . در این حالت سال شمسی از تفاضل سال میلادی با " 622 " بدست می آید . ( چون بین 11 دی تا آخر اسفند قرار داریم . )     

 2-3- سال کبیسه نباشد : 

 دقیقا به مانند الگوریتم سال کبیسه عمل می کنیم ، البته با کمی تفاوت که با مطالعه ی SourcCode متوجه آن خواهید شد . 


 

راهنما  : 

1- بهتر است برای هر دو سال های میلادی کبیسه و غیر کبیسه یک آرایه ی جداگانه در نظر گرفته شود  .

2- برای مقدار دهی به آرایه های سال کبیسه و غیر کبیسه ، در این الگوریتم باید با توجه به جدول زیر  عمل کنیم : 

Length in days Name No.
31 January 1
28 or 29 leap year February 2
31 March 3
30 April 4
31 May 5
30 June 6
31 July 7
31 August 8
30 September 9
31 October 10
30 November 11
31 December 12

به طور مثال ) می خواهیم آرایه ای از سال غیر کبیسه ( not_leap_year ) را با توجه به جدول بالا مقدار دهی کنیم :

مقدار دهی آرایه به این شکل است که :  عنصر قبل  + عنصر بعد  ،  با این شرط که اولین عنصر از آرایه مقدار صفر (0) را دارد .

 not_leap_year = [ 0 , January + 0 , ( January + 0 ) + 28 , .... ]
 
 
 not_leap_year = [ 0 , 0 + 31 , 31 + 28 , 59 + 31 , 90 + 30 , 120 + 31 , 151 + 30 , 181 + 31 , 212 + 31 , 
243 + 30 , 273 + 31 , 304 + 30 ]
 
 

 

نـکتـه 1 : برای not_leap_year ( سال غیر کبیسه ای ) عدد 28 را در نظر می گیریم . برای is_leap_year (سال کبیسه ای ) عدد 29 را در نظر می گیریم . 

نـکتـه 2 : باید دقت داشته باشید که طول آرایه از عدد 12 تجاوز نکند ، چون هر سال 12 ماه دارد . 

 

<< الگوریتم تاریخ جلالی برای جاوا نیز نوشته شده است در صورت نیاز می توانید پیام خصوصی داده تا در انجمن مربوطه قرار گیرد  >>

 برای این سوال 3 پاسخ وجود دارد.
پاسخ به سوال 
سهرابیان  7 سال پیش
+2 0

تابع calcSolarCalendar به صورت یک method تعریف شده و عینا مانند الگوریتم بالا می باشد  . از ویژگی های این الگوریتم : 

  • بدست آوردن تاریخ شمسی از میلادی 
  • بدست آوردن ماه شمسی 
  • بدست آودن روز شمسی 
  • کبیسه گیری سال شمسی ( لینک

نــکــته : دوستان دقت داشته باشید برای تست این الگوریتم فقط از سایت Time.ir استفاده کنید . بقیه سایت ها رو که تست کردم الگوریتم درستی نداشتند.

/** in Swift2.1.1 and XCode7.2 **/

import UNIKit
import Foundation

class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. //call the solarcalendar method CalcSolarCalendar() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. }

// calcSolarDate method
internal func CalcSolarCalendar(){ var difference_between_days:Int = 0
var strMonth = "" var date:Int = 0 var month:Int = 0 var year:Int = 0 //get day , month and year from your divice let date_miladi = NSDate() let calendar = NSCalendar.currentCalendar() let components = calendar.components([.Day , .Month , .Year], fromDate : date_miladi) let year_miladi = components.year let month_miladi = components.month let day_miladi = components.day


//date convert to string and send to the getDayOfWeek method let dateFormater = NSDateFormatter() dateFormater.dateFormat = "yyy-MM-dd" let dateString = dateFormater.stringFromDate(date_miladi)

//day of month let not_leap_year = [0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334] let is_leap_year = [0 , 31 , 60 , 91 , 121 , 152 , 182 , 213 , 244 , 274 , 305 , 335] if ((year_miladi % 4 ) != 0) { date = not_leap_year[month_miladi - 1 ] + day_miladi if(date > 79){ date = date - 79 if(date <= 186){ switch (date % 31){ case 0: month = date / 31 date = 31 break ; default: month = (date / 31) + 1 date = (date % 31) break ; } year = year_miladi - 621 ; }else{ date = date - 186; switch(date % 30){ case 0 : month = (date / 30 ) + 6 date = 30 break; default: month = (date / 30 ) + 7 date = (date % 30) break; } year = year_miladi - 621 } }else{ if((year_miladi > 1996) && (year_miladi % 4) == 1 ){ difference_between_days = 11 }else{ difference_between_days = 10 } date = date + difference_between_days switch(date % 30){ case 0 : month = (date / 30) + 9 date = 30 break; default: month = (date / 30) + 10 date = (date % 30) break; } year = year_miladi - 622; } }else{ date = is_leap_year[month_miladi - 1] + day_miladi if(year_miladi >= 1996){ difference_between_days = 79 }else{ difference_between_days = 80 } if(date > difference_between_days){ date = date - difference_between_days if(date <= 186){ switch (date % 31) { case 0 : month = (date / 31) date = 31 break; default: month = (date / 31) + 1 date = (date % 31) break; } year = year_miladi - 621 }else{ date = date - 186 switch( date % 30){ case 0 : month = (date / 30 ) + 6 date = 30 break; default: month = (date / 30 ) + 7 date = (date % 30 ) break; } year = year_miladi - 621 } }else{ date = date + 10 switch (date % 30){ case 0 : month = (date / 30 ) + 9 date = 30 break; default: month = (date / 30 ) + 10 date = (date % 30) break; } year = year_miladi - 622; } } switch(month){ case 1: strMonth = "فرودین" break; case 2: strMonth = "اردیبهشت" break; case 3: strMonth = "خرداد" break; case 4: strMonth = "تیر" break; case 5: strMonth = "مرداد" break; case 6: strMonth = "شهریور" break; case 7: strMonth = "مهر" break; case 8: strMonth = "آبان" break; case 9: strMonth = "آذر" break; case 10: strMonth = "دی" break; case 11: strMonth = "بهمن" break; case 12: strMonth = "اسفند" break; default: break; } let dateFormatter = NSDateFormatter() dateFormatter.locale = NSLocale(localeIdentifier: "en_US") //casting int to string let int_year_solar:Int = year let String_year = String(int_year_solar) //Converting to Solar date extention (YYY/MM/DD) let format_month = String(format:"%02d" , month) let format_date = String(format: "%02d" , date) print("date Solar is : " + String_year + "/" + format_month + "/" + format_date) print("Month is : " + strMonth)


// date string sened to DayOfWeek Method getDayOfWeek(dateString)
}

// getDayOfWeek method func getDayOfWeek (today:String) { let formatter = NSDateFormatter() formatter.dateFormat = "yyy-MM-dd"
if let todayDate = formatter.dateFromString(today){
let myCalendar = NSCalendar(calendarIdentifier: "gregorian") let myComponents = myCalendar?.components(.Weekday, fromDate: todayDate) let weekDay = myComponents?.weekday let weekDay_solar = ["شنبه" , "یکشنبه" , "‍ دو شنبه" , "سه شنبه" , "چهارشنبه" , "پنج شنبه" , "جمعه"] if(weekDay != 7){ for var i=0 ; i <= weekDay_solar.count ; i++ { if(weekDay == i){ print("day is : " + weekDay_solar[i]) } } }else{ print("day is : " + weekDay_solar[0]) } } } }

/*
output is :
date solar is : 1395/07/02
month is : مهر
day is : جمعه
*/
 

 اگر می خواهید مقادیر تاریخ میلادی را دستی وارد کنید و یا کاربر خودش دستی وارد کند می توانید به روش زیر و با توجه به کد بالا مقادیر را وارد کنید  : 

let year_miladi = 2016
let month_miladi = 9 let day_miladi = 23

 
        /*
output is :
date solar is : 1395/07/02
month is : مهر
day is : جمعه
*/


 
0 0
درود بر شرفت ...خدا خیر دنیا و آخرت رو بهت بده...دستت درد نکنه...ممنون (7 سال پیش)
+1 0
دوستان توصیه ای که برای شما دارم اینکه ، این الگوریتم را سعی کنید به اجزاء مختلفی تقسیم کنید و آن را به صورت کلاس بندی شده بنویسید تا توسعه ی کد در آینده راحت تر باشه و الگوریتم تون زیاد شلوغ نشه . (7 سال پیش)
پاسخ به سوال 
سهرابیان  7 سال پیش
+2 0

سلامی دوباره خدمت دوستان عزیز در انجمن swift  . 

من در سورس کد بالا علاوه بر تبدیل تاریخ و بدست آوردن ماه شمسی  ، متدی برای بدست آوردن روز های هفته با استفاده از Swift نوشتم و برای اینکه درک source code بالا برای شما مشکل نباشه آن ( func getDayOfWeek ) را به صورت جداگانه در این تاپیک قرار می دهم . 

الگوریتم گرفتن روز های هفته از تاریخ میلادی و نمایش آن به صورت روز های هفته در تاریخ شمسی : 

/** Tested in the Swift2.1.1 and XCode7.2 **/
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib.
// get day , month and year form your device let date_miladi = NSDate() let calendar = NSCalendar.currentCalendar() let components = calendar.components([.Day , .Month , .Year], fromDate : date_miladi) //date convert to string let dateFormater = NSDateFormatter() dateFormater.dateFormat = "yyy-MM-dd" let dateString = dateFormater.stringFromDate(date_miladi)
// call the method getDayOfWeek(dateString) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // getDayOfWeek method func getDayOfWeek (today:String) { let formatter = NSDateFormatter() formatter.dateFormat = "yyy-MM-dd" if let todayDate = formatter.dateFromString(today){ let myCalendar = NSCalendar(calendarIdentifier: "gregorian") let myComponents = myCalendar?.components(.Weekday, fromDate: todayDate) let weekDay = myComponents?.weekday let weekDay_solar = ["شنبه" , "یکشنبه" , "‍ دو شنبه" , "سه شنبه" , "چهارشنبه" , "پنج شنبه" , "جمعه"] if(weekDay != 7){ for var i=0 ; i <= weekDay_solar.count ; i++ { if(weekDay == i){ print("day is : " + weekDay_solar[i]) } } }else{ print("day is : " + weekDay_solar[0]) } } } }
 

 نکــته : در هنگام تعریف آرایه در زبان swift وقتی عناصر فارسی داخل آرایه تعریف می کنید باید دقت داشته باشید که عناصر فارسی از سمت راست index گزاری می شوند و اگر اشتباه نکنم این ویژگی در زبان برنامه نویسی جاوا بر عکس است . 

پاسخ به سوال 
سهرابیان  7 سال پیش
+2 0

سؤال از خودم بپرسم : آقای patriot می خوام ورودی را با استفاده از EditText و از کاربر دریافت کنم ولی روز مورد نظر را به درستی برای من نمایش نمی دهد باید چیکار کنم ؟ 

جواب : کاملا حق با شماست به این دلیل که من فقط و فقط تاریخ سیستم را به متد getDayOfWeek ای که نوشتم ارسال می کنم و نه تاریخ ورودی کاربر . بنابراین برای زمانی که بخواهیم ورودی را از کاربر دریافت کنیم باید به شیوه ی زیر الگوریتم را تغییر دهیم : 

//getting input from the user
let year_miladi = 1932
let month_miladi = 9
let day_miladi = 23

//Casting int variable to String
let stryear= String(year_miladi)
let strmonth = String(month_miladi)
let strday = String(day_miladi)

//format (yyy-MM-dd)
let totaldate = stryear + "-" + strmonth + "-" + strday

// send totaldate to getDayOfWeek Method
getDayOfWeek(totaldate)


/*
output is :
date solar is : 1311/07/01
Month is : مهر
day is : جمعه
*/

موفق باشید 

0 0
درود (7 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .