۳ پویا پارسایی
نحوه ذخیره سازی تاریخ و زمان شمسی در دیتابیس
جامعه پی اچ پی ایجاد شده در ۱۳ اردیبهشت ۱۴۰۱

سلام و عرض ادب

سوالم رو با مثال مطرح میکنم که ملموس‌تر باشه.

ما میخوایم فروش ماهیانه یک فروشگاه رو به صورت چارت بهش نمایش بدیم.توی جدول orders یه ستون created_at داریم. با یه sum و group by روی ماه ستون created_at به هدفمون میرسیم.

اما مشکل جایی هست که ما میخوایم فروش رو توی ماه‌های شمسی نشون بدیم ولی رکوردهای ما توی جدول به تاریخ میلادی ثبت شدن و روزهای این دوتا تقویم هم برابر نیستند. به طور مثال یکم اسفند شمسی میشه ۱۵ ماه میلادی. پس اگه بعد از دریافت گزارش ماه رو به شمسی تبدیل کنیم گزارشمون مشکل داره و اطلاعاتش صحیح نیست.

توی یکی از جلسات این دوره دکتر آوند فرمودند که تاریخ رو به شمسی تو دیتابیس ذخیره نکنید.

با این تفاسیر بهترین راه واسه حل این مشکل چیه؟

یه ستون datetime دیگه برای ثبت تاریخ و زمان شمسی به جدول اضافه کنیم اشکالی نداره؟ راه بهتری هست؟

سلام دوست عزیز

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


محمد گازری ۱۳ اردیبهشت ۱۴۰۱، ۱۰:۳۸

فکر کنم متوجه منظورم نشدید. ببینید ما میخوایم مجموع فروش رو به تفکیک ماه بگیریم، هیچ بازه زمانی هم نداریم. به تیکه کد زیر توجه بفرمایید:

// Get selected branch
$branch = Branch::where('id', $request->branch_id)->first();
// query to select and group branch's orders by month
$orders = $branch->orders()->
select([
    \\DB::raw("DATE_FORMAT(created_at, '%Y-%m') as month"),
    \\DB::raw('SUM(order_amount) as amount')
])
    ->groupBy('month')
    ->get();
// convert dateTime to Jalali
$orders->each(function ($item) {
    $item->month = Verta::instance($item->month)->format('%B %Y');
});

ببینید ما orders رو به تفکیک ماه توی دیتابیس میگیریم.

شما میفرمایین قبل از رکورد گیری تاریخ رو تبدیل کنیم. ما که تاریخی نداریم که بخوایم تبدیل کنیم. بعد از دریافت اطلاعات هم که با ورتا تبدیلش میکنیم، چون روزهای ماه‌های شمسی و میلادی مطابقت ندارن، گزارش اشتباه میشه.

پویا پارسایی ۱۳ اردیبهشت ۱۴۰۱، ۱۱:۵۷

سلام مجدد

با عرض پوزش بابت تاخییر الان تاپیکتون رو دیدم

شما میتونید یه ستون در پایگاه دادتون ایجاد کنید (جدای created_at که با tmestamp کار میکنه) و تاریخ شمسی رو به شکل زیر داخلش ذخیره کنید مثلا ستون pdate

139404
YearMonth

نیازی به دخیره باقی تاریخ ندارید و میتونید این کار رو هم کنید ولی نیازی نیست چون بار پردازشی الکی برای تحلیلش ایجاد میشه و برای روز و باقی دیتا بعد از دریافت از ستون created_at تحلیلش میکنید

با این روش میتونید مشکلتون رو حل کنید و روی ماه‌های دلخواه کوئری بزنید

موفق باشید ?

بهترین پاسخ
محمد گازری ۲۳ اردیبهشت ۱۴۰۱، ۰۴:۲۵