مقدمه ای بر تاریخ-fns

کار با تاریخ در جاوا اسکریپت یک درد است. روش های تاریخ بومی اغلب پر حرف و گاها متناقض است – چیزی که آنها را نیز مستعد خطا می کند. اما خبرهای خوبی در راه است. چندین کتابخانه وجود دارد که می تواند دستکاری قدیمی را از بین ببرد. این کتابخانه ها مربوط به تاریخهای JavaScript هستند ، یعنی jQuery برای API محلی DOM چیست.

بگذارید برای شما مثالی بزنم. این پاسخ پذیرفته شده به a است س Stال Stack Overflow با پرسیدن اینکه چگونه آخرین روز ماه را بدست آورید:

var t = new Date();
alert( new Date(t.getFullYear(), t.getMonth() + 1, 0, 23, 59, 59) );

البته که جواب می دهد ، اما بلافاصله مشخص نیست که اعداد پس از آن چه هستند getMonth نشان دادن اکنون این را با قابل خواندن تر مقایسه کنید:

const today = new Date();
console.log( lastDayOfMonth(today) );

که lastDayOfMonth روش ارائه شده توسط date-fns، یک مجموعه ابزار جامع خودآرایی برای دستکاری تاریخ های JavaScript در مرورگر و Node.js.

در این مقاله قصد دارم به شما نشان دهم که چگونه با date-fns بلند شوید و کار کنید. پس از مطالعه می توانید آن را در پروژه های خود رها کرده و از بسیاری از روش های کمکی آن استفاده کنید تا خرما را به راحتی دستکاری کنید. این کد را مانند می کند t.getMonth() + 1, 0, 23, 59, 59 چیزی از گذشته است.

بنابراین ، چرا فقط از Moment.js استفاده نمی شود؟

Moment.js یک کتابخانه خارق العاده برای کار با تاریخ در جاوا اسکریپت است – دارای بسیاری از ویژگی های عالی و مجموعه کاملی از ابزارهای مفید است. با این حال ، خالی از انتقاد نیست.

بسیاری از مردم این واقعیت را نقل می کنند که اشیا Mom Moment قابل تغییر هستند (مانند عملیاتی مانند add، یا subtract شی Mom اصلی Moment را تغییر دهید) زیرا برای توسعه دهندگان گیج کننده و منبع اشکالات است.

همچنین به دلیل بزرگ بودن مورد انتقاد قرار گرفته است. لحظه با الگوریتم های مدرن “لرزش درخت” خوب بازی نمی کند و اگر به بین المللی سازی یا پشتیبانی از منطقه زمانی نیاز دارید ، می توانید به سرعت خود را با یک بسته جاوا اسکریپت نسبتاً بزرگ پیدا کنید.

این امر تا آنجا پیش رفته است که ابزارهای توسعه یافته Chrome این واقعیت را برجسته می کنند که استفاده از Moment می تواند منجر به عملکرد ضعیف شود.

همه اینها حافظه های Moment را به سمت سوق می دهد پروژه را در حالت تعمیر و نگهداری قرار دهید و برای جلوگیری از استفاده لحظه ای در ادامه پروژه های جدید.

ما تشخیص می دهیم که بسیاری از پروژه های موجود ممکن است همچنان از Moment استفاده کنند ، اما ما می خواهیم Moment را از استفاده در پروژه های جدید در حال انجام منصرف کنیم. در عوض ، ما دوست داریم گزینه های جایگزین را توصیه کنید که امروزه گزینه های بسیار خوبی برای استفاده در برنامه های مدرن هستند.

این باعث می شود date-fns یکی از بهترین گزینه ها برای Moment.j باشد.

نصب و راه اندازی

از نسخه دو کتابخانه ، تنها راه نصب date-fns بسته npm است.

npm install date-fns

یا از طریق نخ:

yarn add date-fns

شما می توانید از date-fns هم با سیستم ماژول CommonJS و هم با ماژول ES استفاده کنید:


const { lastDayOfMonth } = require('date-fns');

یا:


import { lastDayOfMonth } from 'date-fns';

متأسفانه در حال حاضر هیچ نسخه CDN از تاریخ-fns موجود نیست. حذف و احیای مجدد احتمالی آن در حال بحث است این شماره GitHub. اما این بدان معنا نیست که شما نمی توانید از آن در مرورگر استفاده کنید ، فقط باید یک مرحله بسته بندی را در گردش کار خود وارد کنید.

بیایید اکنون نحوه انجام این کار را بررسی کنیم.

How-Bundle date-fns برای استفاده در مرورگر

من فرض می کنم شما Node و npm را روی دستگاه خود نصب کرده اید. در غیر این صورت ، لطفاً با آموزش ما در زمینه نصب Node مشورت کنید.

بعد ، نصب کنید بسته. این یک بسته نرم افزاری (مشابه Webpack) است که به شما امکان می دهد JavaScript خود را بسته بندی کرده و در مرورگر سرویس دهید.

npm install -g parcel-bundler

بعد ، یک پروژه جدید با package.json فایل.

mkdir datefns
cd datefns
npm init -y

مانند بالا کتابخانه date-fns را نصب کنید:

npm install date-fns

توجه داشته باشید: این یک ایجاد خواهد کرد date-fns پوشه داخل a node_modules پوشه را در فهرست پروژه خود قرار دهید. اگر به داخل نگاه کنید date-fns پوشه ، پوشه ها و پرونده های بیشتری را مشاهده خواهید کرد. نگران نباشید ، ما مقدار زیادی از این موارد را به مشتری منتقل نخواهیم کرد. ما فقط توابع مورد نیاز خود را انتخاب می کنیم و سپس همه چیز را از طریق بسته اجرا می کنیم تا یک بسته نرم افزاری کوچک و درخت زده ایجاد کنیم.

حالا دو فایل ایجاد کنید ، index.html و index.js.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>date-fns</title>
  </head>
  <body>
    <script src="index.js"></script>
  </body>
</html>
import { lastDayOfMonth } from 'date-fns';

const today = new Date();
console.log(lastDayOfMonth(today));

سرور توسعه داخلی بسته را شروع کنید:

parcel index.html

و حرکت به http: // localhost: 1234. اگر صفحه کنسول مرورگر را باز کنید ، نمی توانید چیزی در صفحه نمایش داده شود. شما باید آخرین روز ماه جاری را وارد کنید.

وقتی نوبت به استقرار می رسد می توانید:

parcel build index.js --experimental-scope-hoisting

برای اینکه Parcel یک بسته کوچک و درخت-لرزه در خروجی داشته باشد dist پوشه

Date-fns استفاده اساسی

حالا که ما فعال شدیم ، بیایید بررسی کنیم که date-fns چه کاری می تواند انجام دهد.

یکی از رایج ترین کارها هنگام کار با خرما ، توانایی قالب بندی مناسب آنهاست. ما می توانیم این کار را با date-fns انجام دهیم عملکرد قالب.

HTML را از صفحه مثال ما در بالا تغییر دهید تا به این صورت باشد:

<body>
  <h1>The date today is <span></span></h1>
  <script src="index.js"></script>
</body>

که در index.js ما می خواهیم واردات format تابع ، که می توانیم تاریخ امروز و یک رشته قالب را منتقل کنیم. سپس می خواهیم نتیجه را به صفحه منتقل کنیم.

import { format } from 'date-fns';

const today = new Date();
const formattedDate = format(today, 'dd.MM.yyyy');

document.querySelector('h1 > span').textContent = formattedDate;

البته ما به a محدود نمی شویم dd.MM.yyyy قالب ، بیایید چیز دیگری را امتحان کنیم:

const formattedDate = format(today, 'PPPP');

این خروجی را به صورت زیر فرمت می کند: Wednesday, September 16th, 2020. می توانید لیست کاملی از گزینه های قالب بندی را پیدا کنید در اسناد.

تغییر محلی

اگر وب سایتی به چند زبان دارید ، date-fns بین المللی سازی زمان و تاریخ را ساده می کند. بیایید به مهمانان آلمانی خود سلام کنیم:

<h1>Heute ist <span></span></h1>

و در پرونده جاوا اسکریپت ، می توانیم زبان محلی را وارد کنیم و آن را به format تابع:

import { format } from 'date-fns';
import { de } from 'date-fns/locale';

const today = new Date();
const formattedDate = format(today, 'PPPP', { locale: de });

document.querySelector('h1 > span').textContent = formattedDate;

این چیزی را در امتداد خط تولید می کند: Heute ist Mittwoch, 16. September 2020.

ممکن است نیاز به گذراندن محلی به عنوان گزینه پیچیده به نظر برسد ، اما برخلاف Moment.js که به طور پیش فرض ساخت شما را با تمام محلی ها افزایش می دهد ، date-fns توسعه دهندگان را مجبور می کند که به صورت دستی و به هنگام نیاز به مکان ها نیاز داشته باشند.

با جستجو در بخش ، می توانید لیستی از محل های موجود را مشاهده کنید node_modules/date-fns/locale پوشه در پروژه شما

تغییرناپذیری ، خلوص و سادگی

یکی از نکات فروش date-fns توضیحات خالص و ساده آن است. این منجر به فهم آسان کد می شود ، که در صورت خراب شدن اشکال زدایی آسان تر است.

بگذارید این را با استفاده از Moment.js به عنوان یک مثال متقابل نشان دهم. همانطور که قبلا ذکر شد ، خرما در Moment قابل تغییر است ، که می تواند منجر به یک رفتار غیر منتظره شود.

const moment = require('moment');
const now = new Date();
const mNow = moment(now);

mNow.add('day', 3);
console.log(mNow.toDate());
mNow.add(3, 'day');
console.log(mNow.toDate());



در اینجا باید چند مورد را یادداشت کنید. لحظات add عملکرد نسبت به نظمی که در آن استدلالهای خود را می پذیرد خسته کننده نیست (اگرچه روش اول اکنون اخطار استهلاک را ارائه می دهد). اما گیج کننده تر این است که اگر تماس بگیرید add چندین بار پشت سر هم ، همان نتیجه را نخواهید گرفت زیرا اشیا لحظه ای قابل تغییر هستند:

mNow.add(3, 'day'); 
mNow.add(3, 'day'); 

اکنون آن را با date-fns مقایسه کنید که آرگومان ها را به یک ترتیب نگه می دارد و همیشه همان نتیجه را برمی گرداند و یک نتیجه جدید را برمی گرداند Date برای هر تماس شی.

import { addDays } from 'date-fns';

const today = new Date();
const threeDaysTime = addDays(3, today);
const sixDaysTime = addDays(threeDaysTime, 3);

console.log(today); 
console.log(threeDaysTime); 
console.log(sixDaysTime); 

همچنین توجه کنید که چگونه نام متد رساتر است (addDays به جای فقط add) ، ثابت نگه داشتن کارها و داشتن یک روش برای انجام یک کار و فقط یک کار.

مقایسه خرما

اگر به لیست پست های موجود در کانال JavaScript سایتپوینت نگاه کنید ، می بینید که برخی از آنها به عنوان منتشر شده در یک تاریخ خاص ذکر شده اند ، در حالی که برخی دیگر به عنوان منتشر شده در X روز قبل ذکر شده اند. اگر بخواهید این مورد را در JavaScript وانیلی پیاده سازی کنید ، ممکن است مدتی طول بکشد ، اما با استفاده از date-fns این یک نسیم است – فقط از روش فاصله.

بیایید دو تاریخ متفاوت را با هم مقایسه کنیم.

import { formatDistance } from 'date-fns';

const startDate = new Date(2020, 8, 16); 
const endDate = new Date(2020, 11, 25); 
const distanceInWords = formatDistance(startDate, endDate);

console.log(`It is ${distanceInWords} until Christmas`);

توجه داشته باشید که ، هنگام کار با JavaScript ، ماهها صفر هستند (به عنوان مثال ماه 11 = دسامبر) ، اما روزها از یک روز حساب می شوند. این بارها و بارها من را تحت تأثیر قرار می دهد.

کار با مجموعه تاریخ ها

Date-fns روش های کمکی بسیار مفیدی دارد که می توانید از طریق آنها انواع مختلف خرما را دستکاری کنید.

سفارش مجموعه ای از تاریخ ها

مثال زیر استفاده می کند مقایسه کنید برای مرتب سازی تاریخ ها به ترتیب صعودی. برای این کار ، اگر تاریخ اول بعد از تاریخ دوم باشد 1 ، اگر تاریخ اول قبل از تاریخ دوم باشد 1 یا اگر تاریخ ها برابر باشد 0 برمی گرداند.

import { compareAsc } from 'date-fns';

const date1 = new Date('2005-01-01');
const date2 = new Date('2010-01-01');
const date3 = new Date('2015-01-01');
const arr = [date3, date1, date2];
const sortedDates = arr.sort(compareAsc);


همانطور که می بینید تاریخ ها به ترتیب صعودی هستند.

روش همتایان به compareAsc است مقایسه کنید.

import { compareDesc } from 'date-fns';
...
const sortedDates = arr.sort(compareDesc);

ایجاد روزهای بین دو تاریخ

برای ایجاد روزهای بین دو تاریخ ، می توانید از روش addDays ما قبلاً ملاقات کردیم ، همچنین eachDayOfInterval یاور که آرایه ای از تاریخها را در محدوده مشخص شده برمی گرداند.

import { addDays, eachDayOfInterval } from 'date-fns';

const today = new Date();
const aWeekFromNow = addDays(today, 7);
const thisWeek = eachDayOfInterval(
  { start: today, end: aWeekFromNow },
);

console.log(thisWeek);


یافتن نزدیکترین تاریخ

یافتن نزدیکترین تاریخ به تاریخ مشخص در آرایه ای از تاریخها با استفاده از نزدیکترین روش. این قطعه کد از مثال قبلی پیروی می کند:

import { addDays, eachDayOfInterval, closestTo } from 'date-fns';
...
const christmas = new Date(2020, 11, 25);
const closestToChristmasDate = closestTo(christmas, thisWeek);

console.log(closestToChristmasDate);

همچنین وجود دارد closeestIndexTo اگر می خواهید به جای آن ، شاخص آرایه را بدست آورید.

تأیید اعتبار یک تاریخ

یاور نهایی که می خواهم به او نگاه کنم ، است روش isV معتبر است که همانطور که از نامش پیداست ، معتبر بودن تاریخ مشخص را بررسی می کند.

با این حال ، به دلیل نحوه برخورد JavaScript با تاریخ ها ، چند مورد خرید وجود دارد که باید از آنها مطلع شوید:

import { isValid } from 'date-fns';

const invalidDate = new Date('2020, 02, 30');
console.log(isValid(invalidDate));

اگر فکر کنید که قطعه فوق باید تولید شود ، بخشیده خواهید شد false، به عنوان 30 فوریه ، 2020 بدیهی است که یک تاریخ نامعتبر است. برای درک اینکه چه اتفاقی می افتد ، وارد شوید new Date('2020, 02, 30') در کنسول مرورگر خود خواهید دید Sun Mar 01 2020 به شما بازگردیم – JavaScript روز اضافی را از اواخر ماه فوریه گرفته و آن را به اول مارس تبدیل کرده است (که البته یک تاریخ معتبر است).

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

import { isValid, parse } from 'date-fns';

const validDate = parse('29.02.2020', 'dd.MM.yyyy', new Date());
const invalidDate = parse('30.02.2020', 'dd.MM.yyyy', new Date());

console.log(validDate);


console.log(invalidDate);


console.log(isValid(validDate));


console.log(isValid(invalidDate));

این روش را می توان به راحتی در یک روش کمکی کمکی استخراج کرد ، مثلاً برای اعتبار سنجی ورودی کاربر در فرم ها ، مفید است.

محدوده های زمانی

یک نقطه ضعف date-fns این است که در حال حاضر هیچ عملکرد کمکی منطقه زمانی مانند Moment.js ندارد ، بلکه منطقه زمانی محلی را که کد در حال اجرا است برمی گرداند.

این پاسخ پشته سرریز برخی از زمینه ها را در مورد چگونگی بومی بودن ارائه می دهد Date اشیا actually در واقع داده های “منطقه زمان واقعی” را ذخیره نمی کنند. در آن بخش متوجه خواهید شد که آنها روشی را برای تنظیم مناطق زمانی بطور طبیعی در JavaScript ذکر کرده اند. این یک راه حل جامع نیست ، اما برای بسیاری از سناریوها که فقط به تبدیل خروجی (از ساعت UTC یا محلی به یک منطقه زمانی خاص) نیاز دارند ، جواب می دهد.

new Date().toLocaleString("en-US", {timeZone: "America/New_York"});

مناطق زمانی در واقع یک مسئله پیچیده برای حل این مسئله هستند MomentJS یک کتابخانه جداگانه برای آن دارد. وجود دارد برای افزودن پشتیبانی منطقه زمانی به date-fns برنامه ریزی می کند، اما در زمان نوشتن این مقاله هنوز در دست انجام است.

با این وجود وجود دارد بسته موجود در npm (بر اساس یک درخواست کشش لغو نشده به date-fns) که پشتیبانی منطقه زمانی را برای date-fns v2.0.0 با استفاده از اضافه می کند Intl API. با 140 بار بارگیری در این هفته محبوب به نظر می رسد ، اما در زمان نوشتن مقاله ، چندین ماه است که به روز نشده است.

گفته شده ، در اینجا نحوه استفاده از آن وجود دارد:

npm i date-fns-tz
import { format, utcToZonedTime } from 'date-fns-tz';

const today = new Date(); 
const timeZone = 'Australia/Brisbane'; 
const timeInBrisbane = utcToZonedTime(today, timeZone);

console.log(`
  Time in Munich: ${format(today, 'yyyy-MM-dd HH:mm:ss')}
  Time in Brisbane: ${format(timeInBrisbane, 'yyyy-MM-dd HH:mm:ss')}
`);



نتیجه

Date-fns یک کتابخانه عالی و عالی است که مجموعه ای از روش های کمکی برای کار با تاریخ و زمان را در JavaScript در نوک انگشتان شما قرار می دهد. در حال توسعه فعال است و اکنون که Moment.js وارد حالت تعمیر و نگهداری شده است ، آن را به جایگزینی عالی برای Moment.js تبدیل می کند.

امیدوارم این مقاله درک و الهام کافی به شما داده باشد تا بتوانید آن را بررسی کنید و استفاده از آن را در پروژه های خود شروع کنید.