• وبلاگ : شايد سخن حق
  • يادداشت : تبديل ساده تاريخ ميلادي به شمسي در SQL Server
  • نظرات : 1 خصوصي ، 22 عمومي
  • ساعت ویکتوریا

    نام:
    ايميل:
    سايت:
       
    متن پيام :
    حداکثر 2000 حرف
    كد امنيتي:
      
      
       1   2      >
     
    + محمد 
    عاااااااااالي بود ممنون
    پاسخ

    تشكر. إن‌شاءالله موفق باشيد.
    + محسن 
    لطفا خروجي اين تاريخ رو ببينين چي ميده
    ("1988-09-23 00:00:00.000")
    پاسخ

    :) ظاهراً شما پي‌نوشت ششم را مطالعه نفرموديد! پس يك نظري به آن بياندازيد. سالي كه شما نوشتيد خارج از دامنه محاسبه اين تابع است. اين تابع بر اساس يك فرمول مطلق عمل نمي‌نمايد. بلكه از يك روز خاصي شروع مي‌كند به شمارش روزها و ماه‌ها و سال‌ها. بنابراين بازه محدودي دارد. همان بازه‌اي كه در آن لحاظ شده است. ولي يك تابعي را يكي از مخاطبين طراحي نموده‌اند كه به نظر مي‌رسد بازه وسيع‌تري داشته باشند. لينك آن را در پي‌نوشت هفتم مي‌يابيد. موفق باشيد و در پناه خدا.
    + ميثم محمودي 
    با سلام.
    جالب اينجاست بعد اين همه سال فقط همين يک مطلب در مورد تاريخ شمسي در sql توي اينترنت موجود بود. ميخواستم خدمت تون عرض کنم بنده خودم براي مشکلاتي که داشتم ، اسکريپتي مشابه اسکريپت شما نوشته ام و الان چندين ساله که دارم ازش استفاده مي کنم و بدون هيچ مشکلي داره کار مي کنه.
    موردي که الان پيش اومده اينکه نياز بنده پيشرفت کرده و من نياز به چندمين روز سال و چندمين هفته سال و ديتايي از اين دست دارم.
    اسکريپتي بابت اين موضوع داريد؟ ممنون ميشم ازتون.
    پاسخ

    سلام. در اين سايت: https://jdf.scr.ir/jdf كدهاي خوبي پيدا مي‌شود. زحمات زيادي هم كشيده‌اند. شايد بتوانيد قسمت‌هايي از كدهاي آن‌ها را تبديل به SQL نماييد. موفق باشيد.
    + نصير 
    بسيار عالي کار ميکنه
    ممنون
    خانواده اي را از نگراني درآورديد با اين فانکشن
    خدا به شما خير بده
    پاسخ

    سلام. خدا را شكر. من هم سال‌هاست دارم از همين تابع استفاده مي‌كنم. تا به حال راضي بودم. تشكر.
    سلام و احترام . ممکنه بفرمائيد کدهائي که نوشته ايد را چگونه در sql server پياده کنم . ببخشيد مبتدي هستم .
    پاسخ

    سلام. مي‌توانيد از آموزش‌هايي مانند: http://www.taktemp.com/1388/08/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-sql-server-%D8%AC%D9%84%D8%B3%D9%87-%D9%87%D9%81%D8%AA%D9%85-2/ و موارد مشابهي مانند: http://barnamenevis.org/showthread.php?222041-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-function-%D8%AF%D8%B1-SQL يا http://www.hozhan.ir/Article/71/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-Stored-Procedure-%D9%88-Function-%D8%AF%D8%B1-SQL-Server/ استفاده بفرماييد. در اينترنت اطلاعات زيادي در اين زمينه به زبان فارسي پيدا مي‌:كنيد. موفق باشيد.
    سلام
    خيلي خيلي ممنون بابت انتشار اين اسکريپ کاربردي و پي‌نوشت‌هاي بعد از اون!

    تابع SDAT که سريع‌تر خروجي رو توليد مي‌کنه و آقاي مهدي‌زاده لطف کردند و منتشرش کردند، در مورد «چندمين روز سال» يعني همون فرمت «SaalRooz» مشکل داره. به نظر مي‌رسه اين مشکل براي تاريخ‌هاي بين 11 دي تا 29 اسفند (مثلا 2015-01-01 تا 2015-03-20) ايجاد مي‌شه.
    يک نمونه از مقايسه خروجي تابع G2J و SDAT:
    http://s9.picofile.com/file/8273810250/DateDimension.PNG

    به هر حال تشکر بابت اشتراک‌گذاري هر دو تابع.
    موفق باشيد
    پاسخ

    سلام. تشكر از اين كه به اين نكته اشاره فرموديد. اميدوارم ايشان مطلب شما را مشاهده كرده و تابع خود را اصلاح نمايند. تابع ايشان فرآيند به ظاهر بسيار پيچيده‌اي دارد كه فهم آن نياز به دقت و بررسي فراوان دارد و من نيز هنوز از آن سر در نياورده‌ام. اما اين تابعي كه بنده منبع اصلي آن را از كامنتي در سايت آقاي فعال‌خواه يافته‌ام، نوشته شده توسط «روح‌اله» در 29 آذر 1393، الگوريتم بسيار ساده‌اي دارد كه به راحتي درك مي‌شود. اگر چه كبيسه‌هاي پنج‌ساله در آن ديده نشده است، ولي هر زمان چنين كبيسه‌هايي رخ داد، به دليل سادگي فرآيند، با اضافه كردن يك IF مي‌توان مشكل را حل نمود. موفق باشيد.
    + بنده 
    الگوريتم تاريخ اشتباه است
    پاسخ

    همين الآن تابع G2J را مجدداً بر اساس همين كد كه در صفحه فوق آمده است در ديتابيس ساختم و با ورودي 2016/10/16 تست كردم و جواب گرفتم: يکشنبه 25 مهر 1395 كه كاملاً صحيح مي‌باشد. اين‌كه مي‌فرماييد الگوريتم اشتباه است، لطفاً بفرماييد كجاي آن غلط است تا اصلاح كنم. فعلاً خروجي تابع كه صحيح است. تشكر.
    + علي 
    سلام؛
    با تشکر از کدهايي که در اختيار بقيه گذاشتيد
    نکته اي رو مي خواستم بگم که به نظر مهم اومد و البته اشتباه خيلي از برنامه نويس هاي عزيز هست. داخل کد آخر براي خروجي از nvarchar(max) استفاده شده که واقعا نبايد اين اتفاق بيوفته. همه ميدونن که max بودن نوع متغير يعني فضاي هارد اشغال شده که البته هم ارزون هست و هم فراوان. اما توجه داشته باشيد که مموري و کش مورد استفاده SQL نه ارزون هست و نه فراوان. اگر از اين پروسيجر براي مثلا يک جدول Log استفاده کنيد ( مثلا براي 10000 رکورد ) اين قضيه خودش رو سرعت و خيلي چيزهاي ديگه نشون ميده.
    nvarchar(30) براي خروجي اين پروسيجر کافي هست.
    موفق باشيد
    پاسخ

    تشكر از نكته خوب و ارزشمندي كه فرموديد. به ميزان منابعي كه به اين طريق مصرف مي‌شود توجه نداشتم. خيلي ممنون.
    + احمدي 
    باسلام
    کد معرفي شده با sql 2005 کار نميکنه
    پاسخ

    سلام. ولي كدي كه در داخل همين پست وبلاگي نوشته‌ام و جديداً ويرايش و اصلاح كردم به نظرم با هر نگارشي از SQL كار كند، زيرا از دستورات عمومي و ساده‌اي استفاده مي‌كند. چند روز پيش تست كردم و تاريخ درست را خروجي داد. راستي، فراموش نفرماييد كه ما براي اولين بار در SQL 2008 حروف فارسي به صورت مستقل داريم (Persian-100) در حالي كه در 2005 از عربي استفاده مي‌شود. دو حرف ي و ك در عربي با فارسي تفاوت دارند. وقتي حروف «ي» و «ک» فارسي بخواهند مورد استفاده قرار بگيرند معمولاً دچار مشكل مي‌شوند. اين احتمال را هم بررسي بفرماييد، با توجه به اين‌كه در ابتداي تابع از حروف فارسي استفاده شده است. براي تست، مي‌توانيد تمام بخش‌هاي فارسي داخل كد را موقتاً به انگليسي بر گردانيد و تست كنيد. اگر جواب داد مشكل از همين تفاوت فارسي و عربي‌ست. موفق باشيد.
    + احمدي 
    مشکل کوتيشن و تک کوتيشن نيست
    پاسخ

    من همين الآن كل كد موجود در لينك داده شده را كپي كردم در نوت‌پد، كوتيشن‌ها را با آپستروف جايگزين كردم، بردم داخل اديتور SQL Server 2008 اجرا كردم. تابع SDAT ساخته شد. با كد ( SELECT [dbo].[SDAT] ("2016/04/09" , "") ) تست كردم، پاسخ داد ( شنبه 21 فروردين 1395 ) كه درست بود. شايد نسخه SQL شما متفاوت است يا دليل ديگري. موفق باشيد.
    + احمدي 

    سلام مجدد

    کدي که در لينک معرفي شده ، در سيستم من خطا ميگيره!

    آيا لازمه که کد ايشون اصلاح بشه؟ يا همين کد، کد نهايي هست؟

    که در اينصورت روي تعاريف متغير ها داراي اشکال هست

    پاسخ

    سلام. احتمال مي‌رود فراموش فرموده باشيد كه كوتيشن‌مارك‌هاي داخل اين كد را با نشان آپستروف جايگزين فرماييد. كوتيشن‌ها دوتايي هستند، ولي آپستروف تكي‌ست. اگر اين جايگزيني انجام نشود، كد خطا مي‌دهد. يك بررسي بفرماييد.
    + احمدي 

    سلام

    اين کد را سال گذشته استفاده ميکردم درست کار ميکرد و لي امثال تاريخ ميلادي را که به شمسي تغيير ميده تاريخ دو روز پيش را نشون ميدهو لطفا يه نگاه بهش بندازيد

    پاسخ

    سلام. صحيح مي‌فرماييد. اين به دليل محاسبه «كبيسه‌»هاست. سال‌هاي ميلادي كبيسه‌هاي خاص خود را دارند و سال‌هاي شمسي نيز. غير از اين‌كه هر چهار سال يك‌بار ما كبيسه داريم، در يك بازه زماني كبيسه‌هاي پنج‌ساله اتفاق مي‌افتند. كد فوق را چند ماه پيش اصلاح كردم كه مشكل كبيسه آن حل شده است. يك كد جديد هم يك بزرگواري نوشته‌اند كه خيلي سريع‌تر از كد فوق است. نشاني آن را در پي‌نوشت هفتم مي‌يابيد. مي‌توانيد از آن استفاده كنيد كه قطعاً بسيار بهتر است. موفق باشيد.
    کد در آدرس زير است جهت تست و استفاده ساير علاقمندان
    اينجا
    پاسخ

    تشكر.
    + MAMEHDI 
    با سلام و خسته نباشيد خدمت شما کدي را که گذاشتيد بعلت اينکه روز به روز اضافه ميکند داراي حلقه طولاني است و روز هفته چه عددي و چه حرفي را اشتباه چاپ ميکند مثلا امروز که يکشنبه 17 آبان 94 و دومين روز هفته است را ميگويد شنبه و اولين روز من داخل کد شما دست بردم و بسيار سريعتر شد و چون تقريبا 90% کد عوض شد هم اسم متغييرها را عوض کردم و هم تعداد آنها را کاهش دادم اگر خواستيد کدش را ميگزارم تا يک تست هم از لحاظ درستي و هم از لحاظ سرعت در رکوردهاي بالا با کد قبلي تست شود تا شايد نياز به جدول ديگر نباشد با تشکر
    پاسخ

    سلام. متغيّر DayCnt را تغيير دادم و مشكل روز يكشنبه حل شد. اما نسبت به الگوريتم آن، بله صحيح مي‌فرماييد. الگوريتم خيلي كندي دارد، ولي قابل فهم‌تر نسبت به ساير الگوريتم‌ها. اگر لطف بفرماييد و كد را ايميل كنيد، آن را در همين پست وبلاگ معرفي خواهم كرد. من كدهاي مختلفي را ديده‌ام تا به حال. ولي علّت اين‌كه اين كد را انتخاب كردم، سادگي بي‌حدّ آن بود كه مي‌‌شود دقيقاً از اتفاقاتي كه در لوپ و حلقه مي‌افتد اطمينان حاصل كرد. البته كد فوق مربوط به بنده نيست و من نيز آن را از كامنت‌هاي وبلاگي ديگر برداشته و در آن دست برده‌ام كه نشاني‌اش در پست ذكر شده است. تشكر.
    + بازم علي 
    سلام.بايد بگم مشکل قبلي بنده حل شد اما يه ايراد و اون اينکه توي تابع دوم(G2J_Fast)نميتونيد فرمت خروجي را تعيين کنيم!
    پاسخ

    سلام. آيا جاي كوتيشن‌مارك‌ها را با آپستروف عوض كرديد؟ من به جهت اين‌كه در وبلاگ نمي‌شد از آپستروف استفاده كرد، كوتيشن‌مارك قرار دادم. تابع به نحوي طراحي شده كه حتي اگر رشته اشتباهي هم در فرمت قرار دهيد، متوقف نشده و كارش را انجام مي‌دهد. يعني تنها كاري كه با رشته فرمت انجام مي‌پذيرد اين است كه پس از توليد تاريخ شمسي، با نمادهاي استفاده شده در رشته فرمت جايگزين مي‌گردد. پس منطقي نيست و نبايد درج فرمت مشكلي در اجراي تابع اصلي ايجاد نمايد. يك اشتباهي هم ممكن است صورت داده باشد و آن اين‌:كه: من دو عدد تابع G2J‌ نوشته‌ام؛ اولي بدون فرمت است و اصلاً چنين پارامتري ندارد و دومي دارد. شما ممكن است تابع اول را ساخته باشيد و معلوم است كه حالا نمي‌توانيد پارامتري به عنوان فرمت براي آن ارسال كنيد. تابع را باز كنيد و ببينيد كدام را ساخته‌ايد. اگر در سطر اول آن پارامتر فرمت ثبت نشده، آن تابع را حذف كنيد؛ DROP و يك بار ديگر تابع دوم G2J كه داراي دو پارامتر و آرگومان است @intDate DATETIME, @Format NVARCHAR را بسازيد.
       1   2      >