هنگام نوشتن کد برای مشخص کردن یک مقدار زمانی، از کلاس یا متدی استفاده کنید که بهترین نیاز شما را برآورده میکند: کلاس Duration، کلاس Period یا متد ChronoUnit.between(). Duration مقدار زمانی را با مقادیر مبتنی بر زمان (ثانیه، نانوثانیه) اندازهگیری میکند. Period از مقادیر مبتنی بر تاریخ (سال، ماه، روز) استفاده میکند.
نکته: یکDurationبه مدت یک روز دقیقاً ۲۴ ساعت است. اما یکPeriodبه مدت یک روز هنگام اضافه شدن به یکZonedDateTimeممکن است بسته به منطقهی زمانی متفاوت باشد، مثلاً اگر در اولین یا آخرین روز ساعت تابستانی رخ دهد.
Duration مناسبترین گزینه برای شرایطی است که زمان مبتنی بر ماشین را اندازهگیری میکند، مانند کدی که از شیء Instant استفاده میکند. شیء Duration بر حسب ثانیه یا نانوثانیه اندازهگیری میشود و از ساختارهای مبتنی بر تاریخ مانند سال، ماه و روز استفاده نمیکند، اگرچه این کلاس متدهایی برای تبدیل به روز، ساعت و دقیقه دارد. Duration میتواند مقدار منفی داشته باشد، مثلاً اگر نقطهی پایان قبل از نقطهی شروع ایجاد شده باشد.
کد زیر مدت زمان بین دو لحظه را بر حسب نانوثانیه محاسبه میکند:
Instant t1 = ...;
Instant t2 = ...;
long ns = Duration.between(t1, t2).toNanos();
کد زیر ۱۰ ثانیه به یک Instant اضافه میکند:
Instant start= ...;
Duration gap = Duration.ofSeconds(10);
Instant later = start.plus(gap);
Duration به خط زمانی متصل نیست و مناطق زمانی یا ساعت تابستانی را ردیابی نمیکند. اضافه کردن Duration معادل یک روز به یک ZonedDateTime دقیقاً ۲۴ ساعت اضافه میکند، صرفنظر از ساعت تابستانی یا سایر تفاوتهای زمانی.
Enum ChronoUnit که در پکیج Temporal مورد بحث قرار گرفت، واحدهای مورد استفاده برای اندازهگیری زمان را تعریف میکند. متد ChronoUnit.between() وقتی مفید است که بخواهید مقدار زمانی را فقط در یک واحد زمانی واحد مانند روز یا ثانیه اندازهگیری کنید. متد between() با تمام اشیاء مبتنی بر Temporal کار میکند اما مقدار را فقط در یک واحد برمیگرداند. کد زیر فاصلهی زمانی بین دو Time Stamp را بر حسب میلیثانیه محاسبه میکند:
Instant previous = ...;
Instant current = ...;
long gap = 0L;
current = Instant.now();
if (previous != null) {
gap = ChronoUnit.MILLIS.between(previous,current);
}
برای تعریف یک مقدار زمانی با مقادیر مبتنی بر تاریخ (سال، ماه، روز)، از کلاس Period استفاده کنید. کلاس Period متدهای Get متعددی مانند getMonths()، getDays() و getYears() دارد تا بتوانید مقدار زمانی را از Period استخراج کنید.
کل بازهی زمانی توسط هر سه واحد با هم نمایش داده میشود: ماه، روز و سال. برای نمایش مقدار زمانی در یک واحد واحد مانند روز، میتوانید از متد ChronoUnit.between() استفاده کنید.
کد زیر سن شما را با فرض تولد در ۱ ژانویه ۱۹۶۰ گزارش میدهد. کلاس Period برای تعیین زمان به سال، ماه و روز استفاده شده. همان بازه بر حسب کل روزها با استفاده از متد ChronoUnit.between() محاسبه و در پرانتز نمایش داده شده است:
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
Period p = Period.between(birthday, today);
long p2 = ChronoUnit.DAYS.between(birthday, today);
IO.println("You are " + p.getYears() + " years, " + p.getMonths() +
" months, and " + p.getDays() +
" days old. (" + p2 + " days total)");
خروجی کد به صورت زیر است:
You are 53 years, 4 months, and 29 days old. (19508 days total)
برای محاسبهی مدت زمان باقیمانده تا تولد بعدی، میتوانید از کد زیر استفاده کنید. کلاس Period برای تعیین مقدار به ماه و روز استفاده شده. متد ChronoUnit.between() مقدار را بر حسب کل روزها برمیگرداند و در پرانتز نمایش داده شده است.
LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
LocalDate nextBDay = birthday.withYear(today.getYear());
// اگر تولد امسال قبلاً گذشته باشد، ۱ به سال اضافه کنید
if (nextBDay.isBefore(today) || nextBDay.isEqual(today)) {
nextBDay = nextBDay.plusYears(1);
}
Period p = Period.between(today, nextBDay);
long p2 = ChronoUnit.DAYS.between(today, nextBDay);
IO.println("There are " + p.getMonths() + " months, and " +
p.getDays() + " days until your next birthday. (" +
p2 + " total)");
خروجی کد به صورت زیر است:
There are 7 months, and 2 days until your next birthday. (216 total)
این محاسبات تفاوتهای منطقهی زمانی را در نظر نمیگیرند. بهعنوان مثال اگر در استرالیا متولد شدهاید اما الان در بنگلور زندگی میکنید، این موضوع محاسبهی دقیق سن شما را کمی تحت تأثیر قرار میدهد. در این شرایط، از Period همراه با کلاس ZonedDateTime استفاده کنید. وقتی Period را به یک ZonedDateTime اضافه میکنید، تفاوتهای زمانی رعایت میشوند.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://dev.java/learn/