LocalDate जैसे java.time ऑब्जेक्ट के साथ काम करते समय आपको अक्सर तारीखों में जटिल बदलाव करने पड़ते हैं, जैसे "महीने का दूसरा मंगलवार" ढूँढना। इन्हें हाथ से निकालने के बजाय आप TemporalAdjusters का उपयोग कर सकते हैं।
java.time.temporal.TemporalAdjusters (ध्यान दीजिए, अंत में बहुवचन का 's' है) यूटिलिटी क्लास कई आम तारीख बदलावों के लिए स्टैटिक मेथड देती है। इन बदलावों को आप किसी टेम्पोरल ऑब्जेक्ट (जैसे LocalDate) पर .with() मेथड से लागू करते हैं।
Using with(TemporalAdjuster) returns a new instance and does not update the existing instance, as java.time objects are immutable.
import java.time.LocalDate;
import java.time.Month;
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;
LocalDate date = LocalDate.of(2024, Month.AUGUST, 15); // 2024-08-15 (a Thursday)
// Use a predefined adjuster: find the last day of the month
LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
// => 2024-08-31
यहाँ कुछ ऐसे प्रमुख एडजस्टर दिए गए हैं जो शेड्यूलिंग की गणनाओं में काम आते हैं:
सप्ताह के किसी दिन की nवीं बार आने वाली तारीख ढूँढने के लिए dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek) का उपयोग कीजिए।
// Find the second Tuesday of August 2024
LocalDate secondTuesday = date.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.TUESDAY));
// => 2024-08-13
firstInMonth(DayOfWeek dayOfWeek) या lastInMonth(DayOfWeek dayOfWeek) का उपयोग कीजिए।
// Find the last Monday of August 2024
LocalDate lastMonday = date.with(TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY));
// => 2024-08-26
next(), previous(), nextOrSame() और previousOrSame() जैसे एडजस्टर वर्तमान तारीख के सापेक्ष सप्ताह के किसी दिए गए दिन की अगली या पिछली बार आने वाली तारीख ढूँढते हैं।
next()/previous(): अगर वर्तमान तारीख वही दिन है तो उसे छोड़ देते हैं।nextOrSame()/previousOrSame(): अगर वर्तमान तारीख वही दिन है तो उसे भी शामिल करते हैं।LocalDate thursday = LocalDate.of(2024, Month.AUGUST, 15); // A Thursday
// Find the next Thursday (exclusive)
LocalDate nextThursday = thursday.with(TemporalAdjusters.next(DayOfWeek.THURSDAY));
// => 2024-08-22
// Find the next Thursday (inclusive) - returns the same date
LocalDate nextOrSameThursday = thursday.with(TemporalAdjusters.nextOrSame(DayOfWeek.THURSDAY));
// => 2024-08-15
// Find the previous Monday (exclusive)
LocalDate previousMonday = thursday.with(TemporalAdjusters.previous(DayOfWeek.MONDAY));
// => 2024-08-12
TemporalAdjuster एक फंक्शनल इंटरफेस है, इसलिए आप अपना खुद का एडजस्टर एक लैम्ब्डा के रूप में लिख सकते हैं, जो बदलने के लिए टेम्पोरल लेता है और बदला हुआ टेम्पोरल लौटाता है। इसे भी पहले से मौजूद एडजस्टरों की तरह .with() से लागू किया जाता है, और यह अंदर से उनका उपयोग कर सकता है।
import java.time.temporal.TemporalAdjuster;
// An adjuster that moves a weekend date to the following Monday
TemporalAdjuster skipWeekend = temporal -> {
DayOfWeek day = DayOfWeek.from(temporal);
if (day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY) {
return temporal.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
}
return temporal;
};
LocalDate saturday = LocalDate.of(2024, Month.AUGUST, 17);
LocalDate monday = saturday.with(skipWeekend);
// => 2024-08-19
TemporalAdjusters क्लास के इन एडजस्टरों का उपयोग करने से तारीखों से जुड़े काम बहुत आसान हो सकते हैं।
न्यूयॉर्क का वह ब्यूटी सैलून, जिसकी मदद आपने बुकिंग अप फ़ॉर ब्यूटी अभ्यास में की थी, अच्छा चल रहा है और उसके कई ग्राहक अब नियमित हो गए हैं। हर बार अलग से बुकिंग करने के बजाय नियमित ग्राहक का एक स्थायी इंतज़ाम होता है: "हर दूसरा मंगलवार", "महीने का अंतिम शुक्रवार" और इसी तरह के और भी। सैलून के मालिक ने आपसे एक ऐसा हेल्पर बनाने को कहा है जो इन इंतज़ामों के पीछे की तारीखें निकालता है, और साथ ही सैलून के हर महीने के अपने काम की तारीखें भी।
SalonCalendar.standingAppointment() मेथड लागू कीजिए, जो एक साल, एक महीना, कौन-सी बार (1 पहली बार के लिए, 2 दूसरी बार के लिए, और इसी तरह) और सप्ताह का एक दिन लेता है।
यह उस महीने में सप्ताह के उस दिन की उसी बार की तारीख लौटाता है:
SalonCalendar calendar = new SalonCalendar();
calendar.standingAppointment(2024, Month.AUGUST, 2, DayOfWeek.TUESDAY);
// => LocalDate.of(2024, 8, 13)
कुछ नियमित ग्राहक महीने में अपने दिन की अंतिम बार पसंद करते हैं।
SalonCalendar.lastAppointment() मेथड लागू कीजिए, जो एक साल, एक महीना और सप्ताह का एक दिन लेता है और उस महीने में सप्ताह के उस दिन की अंतिम बार की तारीख लौटाता है:
SalonCalendar calendar = new SalonCalendar();
calendar.lastAppointment(2024, Month.AUGUST, DayOfWeek.FRIDAY);
// => LocalDate.of(2024, 8, 30)
फ्रंट डेस्क पर कोई ग्राहक "अगला शनिवार" माँगता है।
अगर जिस दिन वे पूछते हैं वह दिन खुद शनिवार है, तो उनका मतलब उसी दिन से है।
SalonCalendar.nextAvailable() मेथड लागू कीजिए, जो एक तारीख और सप्ताह का एक दिन लेता है और दी गई तारीख को या उसके बाद की पहली ऐसी तारीख लौटाता है जो सप्ताह के उस दिन पड़ती है:
SalonCalendar calendar = new SalonCalendar();
calendar.nextAvailable(LocalDate.of(2024, 8, 15), DayOfWeek.SATURDAY);
// => LocalDate.of(2024, 8, 17)
calendar.nextAvailable(LocalDate.of(2024, 8, 17), DayOfWeek.SATURDAY);
// => LocalDate.of(2024, 8, 17)
सैलून हर महीने के अंतिम दिन अपना हिसाब-किताब बंद करता है।
लेकिन सैलून सप्ताहांत में बंद रहता है, इसलिए जब महीने का अंतिम दिन शनिवार या रविवार को पड़ता है, तो हिसाब-किताब उससे पहले वाले शुक्रवार को बंद होता है।
SalonCalendar.bookkeepingDay() मेथड लागू कीजिए, जो एक साल और एक महीना लेता है और उस महीने का हिसाब-किताब वाला दिन लौटाता है:
SalonCalendar calendar = new SalonCalendar();
calendar.bookkeepingDay(2024, Month.SEPTEMBER);
// => LocalDate.of(2024, 9, 30)
calendar.bookkeepingDay(2024, Month.AUGUST);
// => LocalDate.of(2024, 8, 30)
कर्मचारियों को हर महीने की 15 तारीख को वेतन मिलता है, उसी सप्ताहांत वाले नियम के साथ: जब 15 तारीख शनिवार या रविवार को पड़ती है, तो वेतन उससे पहले वाले शुक्रवार को मिलता है। इस नियम को दूसरी बार लिखने के बजाय इसे एक ऐसा एडजस्टर बना दीजिए जिसे दोबारा इस्तेमाल किया जा सके।
SalonCalendar.precedingWorkday() मेथड लागू कीजिए, जो एक TemporalAdjuster लौटाता है। यह कार्यदिवस को जैसा है वैसा ही छोड़ देता है और शनिवार या रविवार को उससे पहले वाले शुक्रवार पर ले जाता है।
इसके बाद उसी एडजस्टर का इस्तेमाल करते हुए SalonCalendar.payday() मेथड लागू कीजिए, जो एक साल और एक महीना लेता है:
SalonCalendar calendar = new SalonCalendar();
LocalDate.of(2024, 6, 15).with(calendar.precedingWorkday());
// => LocalDate.of(2024, 6, 14)
calendar.payday(2024, Month.JUNE);
// => LocalDate.of(2024, 6, 14)
calendar.payday(2024, Month.AUGUST);
// => LocalDate.of(2024, 8, 15)
आप चाहें तो वापस जाकर bookkeepingDay() में भी इस एडजस्टर का इस्तेमाल कर सकते हैं।
Exercism पर साइन अप कीजिए और Java को 27 कॉन्सेप्ट159 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।