منطقهی زمانی (Time Zone) ناحیهای از زمین است که در آن ساعت استاندارد یکسانی استفاده میشود. هر منطقهی زمانی با یک شناسه (Identifier) توصیف میشود و معمولاً قالب منطقه/شهر (مانند Asia/Tokyo) دارد و Offset نسبت به ساعت گرینویچ/UTC را نیز شامل میشود. بهعنوان مثال Offset توکیو +09:00 است.
رابط Date-Time دو کلاس برای مشخص کردن منطقهی زمانی یا Offset ارائه میدهد:
ZoneId شناسهی منطقهی زمانی را مشخص کرده و قوانین تبدیل بین یک Instant و LocalDateTime را ارائه میدهد.ZoneOffset Offset نسبت به ساعت گرینویچ/UTC را مشخص میکند.Offset ها نسبت به ساعت گرینویچ/UTC معمولاً به صورت ساعت کامل تعریف میشوند، اما استثناهایی وجود دارد. کد زیر فهرستی از تمام مناطق زمانی با Offset غیرساعتکامل را چاپ میکند:
Set<String> allZones = ZoneId.getAvailableZoneIds();
LocalDateTime dt = LocalDateTime.now();
// ساخت List از مجموعهی مناطق زمانی و مرتبسازی
List<String> zoneList = new ArrayList<>(allZones);
zoneList.sort(Comparator.naturalOrder());
for (String zone : zoneList) {
ZoneId zoneId = ZoneId.of(zone);
ZonedDateTime zdt = dt.atZone(zoneId);
ZoneOffset offset = zdt.getOffset();
int secondsOfHour = offset.getTotalSeconds() % (60 * 60);
String out = String.format("%35s %10s", zone, offset);
// فقط مناطق زمانی با Offset غیرساعتکامل
// را چاپ کن
if (secondsOfHour != 0) {
IO.println(out);
}
}
این مثال فهرست زیر را چاپ میکند. توجه کنید نتیجه بسته به نسخهی JDK شما متفاوت خواهد بود:
America/St_Johns -02:30
Asia/Calcutta +05:30
Asia/Colombo +05:30
Asia/Kabul +04:30
Asia/Kathmandu +05:45
Asia/Katmandu +05:45
Asia/Kolkata +05:30
Asia/Rangoon +06:30
Asia/Tehran +03:30
Asia/Yangon +06:30
Australia/Adelaide +09:30
Australia/Broken_Hill +09:30
Australia/Darwin +09:30
Australia/Eucla +08:45
Australia/LHI +10:30
Australia/Lord_Howe +10:30
Australia/North +09:30
Australia/South +09:30
Australia/Yancowinna +09:30
Canada/Newfoundland -02:30
Indian/Cocos +06:30
Iran +03:30
NZ-CHAT +12:45
Pacific/Chatham +12:45
Pacific/Marquesas -09:30
رابط Date-Time سه کلاس مبتنی بر Temporal دارد که با مناطق زمانی کار میکنند:
ZonedDateTime تاریخ و زمان را با منطقهی زمانی متناظر و Offset نسبت به گرینویچ/UTC مدیریت میکند.OffsetDateTime تاریخ و زمان را با Offset نسبت به گرینویچ/UTC و بدون شناسهی منطقهی زمانی مدیریت میکند.OffsetTime زمان را با Offset نسبت به گرینویچ/UTC و بدون شناسهی منطقهی زمانی مدیریت میکند.چه زمانی از OffsetDateTime به جای ZonedDateTime استفاده میکنید؟ اگر نرمافزار پیچیدهای مینویسید که قوانین خودش را برای محاسبات تاریخ و زمان بر اساس موقعیت جغرافیایی مدل میکند، یا اگر Time Stamp هایی را در پایگاهداده ذخیره میکنید که فقط Offset مطلق نسبت به گرینویچ/UTC را ردیابی میکنند، ممکن است بخواهید از OffsetDateTime استفاده کنید. همچنین XML و سایر فرمتهای شبکهای انتقال تاریخ-زمان را به صورت OffsetDateTime یا OffsetTime تعریف میکنند.
اگرچه هر سه کلاس Offset نسبت به گرینویچ/UTC را حفظ میکنند، فقط ZonedDateTime از ZoneRules (بخشی از پکیج java.time.zone) استفاده میکند تا تعیین کند Offset چگونه برای یک منطقهی زمانی خاص تغییر میکند. بهعنوان مثال بیشتر مناطق زمانی هنگام جلو بردن ساعت به ساعت تابستانی یک Gap (معمولاً ۱ ساعت) و هنگام عقب بردن به ساعت استاندارد یک Overlap (تکرار آخرین ساعت قبل از انتقال) تجربه میکنند. کلاس ZonedDateTime این سناریو را پشتیبانی میکند اما کلاسهای OffsetDateTime و OffsetTime که به ZoneRules دسترسی ندارند، این کار را انجام نمیدهند.
کلاس ZonedDateTime در واقع کلاس LocalDateTime را با کلاس ZoneId ترکیب میکند. این کلاس برای نمایش تاریخ کامل (سال، ماه، روز) و زمان (ساعت، دقیقه، ثانیه، نانوثانیه) همراه با منطقهی زمانی (منطقه/شهر مانند Europe/Paris) استفاده میشود.
کد زیر زمان حرکت پرواز از سانفرانسیسکو به توکیو را بهصورت ZonedDateTime در منطقهی زمانی America/Los_Angeles تعریف میکند. متدهای withZoneSameInstant() و plusMinutes() برای ایجاد نمونهی ZonedDateTime نمایانگر زمان رسیدن پیشبینیشده در توکیو پس از پرواز ۶۵۰ دقیقهای استفاده شدهاند. متد ZoneRules.isDaylightSavings() تعیین میکند آیا هنگام رسیدن پرواز به توکیو ساعت تابستانی فعال است یا خیر.
شیء DateTimeFormatter برای فرمتبندی نمونههای ZonedDateTime جهت چاپ استفاده میشود:
DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm a");
// حرکت از سانفرانسیسکو در ۲۰ ژوئیه ۲۰۱۳ ساعت ۱۹:۳۰
LocalDateTime leaving = LocalDateTime.of(2013, Month.JULY, 20, 19, 30);
ZoneId leavingZone = ZoneId.of("America/Los_Angeles");
ZonedDateTime departure = ZonedDateTime.of(leaving, leavingZone);
try {
String out1 = departure.format(format);
System.out.printf("LEAVING: %s (%s)%n", out1, leavingZone);
} catch (DateTimeException exc) {
System.out.printf("%s can't be formatted!%n", departure);
throw exc;
}
// پرواز ۱۰ ساعت و ۵۰ دقیقه، یعنی ۶۵۰ دقیقه
ZoneId arrivingZone = ZoneId.of("Asia/Tokyo");
ZonedDateTime arrival = departure.withZoneSameInstant(arrivingZone)
.plusMinutes(650);
try {
String out2 = arrival.format(format);
System.out.printf("ARRIVING: %s (%s)%n", out2, arrivingZone);
} catch (DateTimeException exc) {
System.out.printf("%s can't be formatted!%n", arrival);
throw exc;
}
if (arrivingZone.getRules().isDaylightSavings(arrival.toInstant())){
System.out.printf(" (%s daylight saving time will be in effect.)%n",
arrivingZone);
} else{
System.out.printf(" (%s standard time will be in effect.)%n",
arrivingZone);
}
خروجی به صورت زیر است:
LEAVING: Jul 20 2013 07:30 PM (America/Los_Angeles)
ARRIVING: Jul 21 2013 10:20 PM (Asia/Tokyo)
(Asia/Tokyo standard time will be in effect.)
کلاس OffsetDateTime در واقع کلاس LocalDateTime را با کلاس ZoneOffset ترکیب میکند. این کلاس برای نمایش تاریخ کامل (سال، ماه، روز) و زمان (ساعت، دقیقه، ثانیه، نانوثانیه) همراه با Offset نسبت به گرینویچ/UTC (+/-ساعت:دقیقه مانند +06:00 یا -08:00) استفاده میشود.
مثال زیر از OffsetDateTime با متد TemporalAdjusters.lastInMonth() برای پیدا کردن آخرین پنجشنبهی ژوئیه ۲۰۱۳ استفاده میکند.
// پیدا کردن آخرین پنجشنبهی ژوئیه ۲۰۱۳
LocalDateTime localDate = LocalDateTime.of(2013, Month.JULY, 20, 19, 30);
ZoneOffset offset = ZoneOffset.of("-08:00");
OffsetDateTime offsetDate = OffsetDateTime.of(localDate, offset);
OffsetDateTime lastThursday =
offsetDate.with(TemporalAdjusters.lastInMonth(DayOfWeek.THURSDAY));
System.out.printf("The last Thursday in July 2013 is the %sth.%n",
lastThursday.getDayOfMonth());
خروجی اجرای این کد:
The last Thursday in July 2013 is the 25th.
کلاس OffsetTime در واقع کلاس LocalTime را با کلاس ZoneOffset ترکیب میکند. این کلاس برای نمایش زمان (ساعت، دقیقه، ثانیه، نانوثانیه) همراه با Offset نسبت به گرینویچ/UTC (+/-ساعت:دقیقه مانند +06:00 یا -08:00) استفاده میشود.
کلاس OffsetTime در همان شرایطی استفاده میشود که کلاس OffsetDateTime استفاده میشود، اما وقتی ردیابی تاریخ مورد نیاز نیست.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://dev.java/learn/