Metabase

ConvertTimezone

تابع convertTimezone یک timestamp را با در نظر گرفتن اختلاف منطقهٔ زمانی (Time zone) به منطقهٔ زمانی مقصد منتقل می‌کند؛ یعنی با اضافه یا کم کردن بازهٔ زمانی مناسب، مقدار جدید را برمی‌گرداند.

SyntaxExample
convertTimezone(column, target, source)convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Eastern")
شِفت دادن timestamp از منطقهٔ مبدأ به منطقهٔ مقصدمقدار 2022-12-28T09:00:00، نمایش به‌صورت December 28, 2022 9:00 AM

کار با timestamp و منطقهٔ زمانی معمولاً پر از ریزه‌کاری و خطا است، و اشکال‌ها هم سخت کشف می‌شوند. به همین خاطر بهتر است فقط وقتی از convertTimezone استفاده کنید که تفسیر داده‌های شما به مرزهای زمانی (Time-based cutoffs) حساس است.

مثلاً اگر فقط در حال شمارش لاگین‌های کاربران در طول زمان هستید، شاید اهمیت نداشته باشد که بعضی لاگین‌ها به‌جای دوشنبه، سه‌شنبه حساب شوند. اما اگر متابیس را برای کارهای دقیقی مثل محاسبهٔ مالیات استفاده می‌کنید، شما (و سازمان‌های قانونی) احتمالاً به تفاوت بین تراکنش‌های ۳۱ دسامبر و ۱ ژانویه خیلی حساس هستید.

منطقه‌های زمانی پشتیبانی‌شده

متابیس از tz database time zones پشتیبانی می‌کند.

پارامترها

column می‌تواند یکی از موارد زیر باشد:

  • نام یک ستون timestamp،
  • یک عبارت سفارشی که یک timestamp برمی‌گرداند،
  • یا یک رشته (String) با فرمت "YYYY-MM-DD" یا "YYYY-MM-DDTHH:MM:SS".

target:

  • نام منطقهٔ زمانی مقصد که می‌خواهید timestamp به آن تبدیل شود.

source:

  • نام منطقهٔ زمانی فعلی ستون شما.
  • برای ستون‌ها یا عبارت‌هایی با نوع دادهٔ timestamp بدون time zone الزامی است.
  • برای ستون‌ها یا عبارت‌هایی با نوع دادهٔ timestamp با time zone اختیاری است.
  • برای اطلاعات بیشتر، بخش انواع دادهٔ پذیرفته‌شده را ببینید.

ما از نام‌های منطقهٔ زمانی در tz database پشتیبانی می‌کنیم (مثل "Canada/Eastern" به‌جای "EST").

ساخت تاریخ‌های گزارشی سفارشی

فرض کنید داده‌های سری زمانی دارید که در یک یا چند منطقهٔ زمانی ذخیره شده‌اند (Source Time)، و می‌خواهید تاریخ‌های گزارشی سفارشی برای تیمی که در EST کار می‌کند بسازید.

Source TimeTeam Report Time (EST)
December 28, 2022, 10:00:00December 28, 2022, 07:00:00
December 28, 2022, 21:00:00December 28, 2022, 19:00:00
December 27, 2022, 08:00:00December 27, 2022, 05:00:00

اگر ستون Source Time به‌صورت timestamp with time zone یا timestamp with offset ذخیره شده باشد، فقط کافی است پارامتر target را مشخص کنید:

convertTimezone([Source Time], "Canada/Eastern")

اگر Source Time به‌صورت timestamp بدون time zone ذخیره شده باشد، حتماً باید منطقهٔ زمانی مبدأ (source) را هم مشخص کنید (که معمولاً همان time zone دیتابیس شما است):

convertTimezone([Source Time], "Canada/Eastern", "UTC")

بهتر است ستون‌هایی را که نتیجهٔ convertTimezone هستند با نام منطقهٔ زمانی مقصد (مثلاً *_EST) برچسب بزنید، یا منطقهٔ زمانی مقصد را در متادیتای مدل ثبت کنید. این کار وقتی کسی اختلاف بین اعداد را زیر سؤال می‌برد، خیلی کمکتان می‌کند.

اگر نتیجه‌ای که می‌گیرید مطابق انتظار نیست:

انتخاب منطقهٔ زمانی مبدأ (Choosing a source time zone)

موقع انجام تبدیل منطقهٔ زمانی، باید بدانید دادهٔ خام شما در چه منطقهٔ زمانی ثبت شده است. حتی در یک جدول، سؤال یا مدل، ممکن است ستون‌ها (یا ردیف‌های) مختلف، «منطقهٔ زمانی مبدأ» متفاوتی داشته باشند.

Possible source time zoneتوضیحمثال
Client time zoneمنطقهٔ زمانی‌ای که رویداد در آن اتفاق افتاده است.یک سرویس وب‌آنالیتیکس ممکن است زمان را در منطقهٔ زمانی محلی هر کاربر سایت ذخیره کند.
Database time zoneمتادیتای منطقهٔ زمانی که روی timestampهای دیتابیس اضافه شده است.رویهٔ رایج این است که همهٔ timestampها در UTC ذخیره شوند.
No time zoneبدون متادیتای منطقهٔ زمانیدیتابیس‌ها شما را مجبور نمی‌کنند timestamp را حتماً با اطلاعات time zone ذخیره کنید.
Metabase report time zoneمنطقهٔ زمانی‌ای که متابیس برای نمایش تاریخ‌ها و زمان‌ها استفاده می‌کند.مثلاً متابیس می‌تواند زمان‌ها را در PST نمایش دهد، حتی اگر در دیتابیس به‌صورت UTC ذخیره شده باشند.

برای مثال، فرض کنید جدولی دارید که در هر ردیف یک بازدیدکنندهٔ وب‌سایت را نگه می‌دارد. فقط با دیدن مقدار December 28, 2022, 12:00 PM معلوم نیست که این timestamp خام:

  • در time zone دیتابیس (معمولاً UTC) ذخیره شده،
  • بدون اطلاعات time zone ذخیره شده (مثلاً اگر کاربر در HKT باشد، همان مقدار ممکن است «ضمنی» به‌معنای زمان هنگ‌کنگ باشد)،
  • یا در گزارش متابیس طبق report time zone نمایش داده می‌شود.

برای جزئیات بیشتر، بخش محدودیت‌ها را ببینید.

انواع دادهٔ پذیرفته‌شده (Accepted data types)

Data typeسازگار با convertTimezone
String
Number
Timestamp
Boolean
JSON

در این سند از واژه‌های "timestamp" و "datetime" برای اشاره به هر نوع دادهٔ زمانی‌ای که متابیس پشتیبانی می‌کند استفاده می‌کنیم.

اگر timestampها در دیتابیس شما به‌صورت String یا عدد ذخیره شده‌اند، ادمین می‌تواند آن‌ها را از صفحهٔ Table Metadata به نوع timestamp Cast کند.

برای این‌که از convertTimezone بدون خطا و اشتباهات ظریف استفاده کنید، باید بدانید چند نوع اصلی timestamp وجود دارد:

Data typeتوضیحمثال
timestamp with time zoneاز موقعیت جغرافیایی/منطقهٔ زمانی خبر دارد2022-12-28T12:00:00 AT TIME ZONE 'America/Toronto'
timestamp with offsetاز اختلاف زمانی نسبت به UTC آگاه است2022-12-28T12:00:00-04:00
timestamp without time zoneبدون اطلاعات time zone2022-12-28T12:00:00

بخش اول timestamp معمولاً در UTC است؛ منطقهٔ زمانی یا offset مشخص می‌کند چقدر باید جمع یا کم کنید تا زمان محلی به‌دست بیاید.

convertTimezone با هر سه نوع timestamp کار می‌کند، اما خروجی آن همیشه یک timestamp بدون time zone خواهد بود.

محدودیت‌ها (Limitations)

تابع convertTimezone در حال حاضر برای دیتابیس‌های زیر در دسترس نیست:

  • Amazon Athena
  • Databricks
  • Druid
  • MongoDB
  • Presto
  • SparkSQL
  • SQLite
  • Metabase Sample Database

نکاتی دربارهٔ منطقهٔ زمانی مبدأ

متابیس timestampهایی را که بدون time zone یا offset هستند، بدون تنظیم خاصی نمایش می‌دهد؛ به‌همین خاطر هنگام استفاده از convertTimezone باید روی انتخاب منطقهٔ زمانی مبدأ دقت زیادی داشته باشید.

Metabase report time zone فقط روی داده‌هایی با نوع timestamp with time zone یا timestamp with offset اثر می‌گذارد. برای مثال:

Raw timestamp در دیتابیس شمانوع دادهReport time zoneنمایش در متابیس
2022-12-28T12:00:00 AT TIME ZONE 'CST'timestamp with time zone'Canada/Eastern'Dec 28, 2022, 1:00 PM
2022-12-28T12:00:00-06:00timestamp with offset'Canada/Eastern'Dec 28, 2022, 1:00 PM
2022-12-28T12:00:00timestamp without time zone'Canada/Eastern'Dec 28, 2022, 12:00 PM

Metabase report time zone روی خروجی convertTimezone اعمال نمی‌شود. برای مثال:

convertTimezone("2022-12-28T12:00:00 AT TIME ZONE 'Canada/Central'", "Canada/Pacific", "Canada/Central")

یک timestamp بدون time zone برمی‌گرداند:

2022-12-28T04:00:00

که در متابیس به‌صورت:

Dec 28, 2022, 4:00 AM

نمایش داده می‌شود.

اگر روی یک timestamp بدون time zone از convertTimezone استفاده می‌کنید، حتماً source را 'UTC' قرار دهید؛ در غیر این صورت timestamp شما به اندازهٔ اشتباهی شِفت داده می‌شود. مثلاً اگر timestamp ما در واقع «ضمنی» در CST باشد، ولی بدون time zone ذخیره شده باشد، باید برای به‌دست آوردن نتیجه правиль، 'UTC' را به‌عنوان مبدأ استفاده کنیم، نه 'CST'.

اگر اشتباهاً 'CST' را برای source یک timestamp بدون time zone بگذاریم:

convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Central")

نتیجهٔ خام:

2022-12-28T10:00:00

خواهد بود که در متابیس به‌صورت:

Dec 28, 2022, 10:00 AM

نمایش داده می‌شود؛ یعنی ۶ ساعت اختلاف ناخواسته.

در این بخش توابع و فرمول‌هایی را می‌بینید که معادل convertTimezone در متابیس عمل می‌کنند و بسته به ابزار می‌توانید از آن‌ها استفاده کنید:

SQL

وقتی با Query builder یک سؤال می‌سازید، متابیس تنظیمات گرافیکی (فیلترها، خلاصه‌سازی و غیره) را به یک کوئری تبدیل و آن را روی دیتابیس اجرا می‌کند.

اگر داده‌های نمونهٔ بخش بالا به‌صورت timestamp بدون time zone در PostgreSQL ذخیره شده باشد:

SELECT source_time::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'America/Toronto' AS team_report_time_est

معادل این عبارت در متابیس است:

convertTimezone([Source Time], "Canada/Eastern", "UTC")

اگر source_time از نوع timestamp with time zone یا timestamp with offset باشد (مثلاً در Snowflake)، دیگر لازم نیست در SQL یا متابیس، source را مشخص کنید:

SELECT convert_timezone('America/Toronto', source_time) AS team_report_time_est

معادل:

convertTimezone([Source Time], "Canada/Eastern")

است. توجه کنید که نام منطقه‌های زمانی به دیتابیس شما بستگی دارد (مثلاً Snowflake بسیاری از مخفف‌های time zone مثل EST را قبول نمی‌کند).

Spreadsheets

اگر داده‌های نمونهٔ بخش گزارش سفارشی در یک Spreadsheet باشد و «Source Time» در ستون A قرار داشته باشد، می‌توانید با کم‌کردن صریحِ اختلاف ساعت، آن را به EST تبدیل کنید:

A1 - TIME(5, 0, 0)

که معادل:

convertTimezone([Source Time], "Canada/Eastern")

در متابیس است.

Python

اگر داده‌های نمونهٔ بخش بالا در یک DataFrame پانداس ذخیره شده باشد، می‌توانید ابتدا ستون Source Time را به timestamp همراه با time zone تبدیل کنید، و بعد آن را به EST ببرید:

df["Source Time (UTC)"] = pd.to_datetime(df["Source Time"], utc=True)
df["Team Report Time (EST)"] = df["Source Time (UTC)"].dt.tz_convert(tz="Canada/Eastern")

این منطق معادل یک convertTimezone تو در تو است:

convertTimezone(convertTimezone([Source Time], "UTC"), "Canada/Eastern", "UTC")

مطالعهٔ بیشتر