הצג את כל אזורי הזמן עם GMT ו- UTC ב- Java

1. סקירה כללית

בכל פעם שאנו מתמודדים עם זמנים ותאריכים, אנו זקוקים למסגרת התייחסות. הסטנדרט לכך הוא UTC, אך אנו רואים גם GMT בכמה יישומים.

בקיצור, UTC הוא הסטנדרט, בעוד ש- GMT הוא אזור זמן.

זה מה שוויקיפדיה אומרת לנו לגבי השימוש:

לרוב המטרות, UTC נחשב להחלפה עם זמן גריניץ '(GMT), אך GMT אינו מוגדר עוד במדויק על ידי הקהילה המדעית.

במילים אחרות, ברגע שנרכיב רשימה עם קיזוז אזור הזמן ב- UTC, יהיה לנו אותה גם ל- GMT.

ראשית, נסתכל על דרך Java 8 להשיג זאת ואז נראה כיצד נוכל להשיג את אותה התוצאה ב- Java 7.

2. קבלת רשימת אזורים

ראשית עלינו לאחזר רשימה של כל אזורי הזמן שהוגדרו.

לצורך זה, ה ZoneId בכיתה יש שיטה סטטית שימושית:

הגדר availableZoneIds = ZoneId.getAvailableZoneIds ();

ואז נוכל להשתמש ב- מַעֲרֶכֶת כדי ליצור רשימה ממוינת של אזורי זמן עם הקיזוזים המתאימים שלהם:

רשימה ציבורית getTimeZoneList (בסיס OffsetBase) {LocalDateTime עכשיו = LocalDateTime.now (); להחזיר ZoneId.getAvailableZoneIds (). stream () .map (ZoneId :: of). sorted (חדש ZoneComparator ()) .map (id -> String.format ("(% s% s)% s", base, getOffset (now, id), id.getId ())) .collect (Collectors.toList ()); }

השיטה לעיל משתמשת ב- enum פרמטר המייצג את הקיזוז אותו אנו רוצים לראות:

פומבי enum OffsetBase {GMT, UTC}

עכשיו בואו נעבור על הקוד ביתר פירוט.

לאחר שאחזרנו את כל מזהי האזור הזמינים, אנו זקוקים להתייחסות זמן בפועל המיוצגת על ידי LocalDateTime.now ().

לאחר מכן, אנו משתמשים ב- Java זרם ממשק API שיחזור על כל ערך בערכת אזור הזמן שלנו חוּט מזהים ולהפוך אותו לרשימה של אזורי זמן מעוצבים עם הקיזוז המתאים.

עבור כל אחת מהערכים הללו, אנו מייצרים a ZoneId מופע עם מפה (ZoneId :: of).

3. קבלת קיזוזים

עלינו למצוא קיזוזי UTC בפועל. לדוגמא, במקרה של שעון מרכז אירופה, הקיזוז יהיה +01:00.

כדי לקבל את קיזוז UTC עבור כל אזור נתון, נוכל להשתמש בו GetOffset של LocalDateTime () שיטה.

שים לב גם שג'אווה מייצגת +00:00 קיזוזים כמו ז.

אז, להיות בעל מראה עקבי חוּט עבור אזורי זמן עם קיזוז אפס, נחליף ז עם +00:00:

מחרוזת פרטית getOffset (LocalDateTime dateTime, ZoneId id) {return dateTime .atZone (id) .getOffset () .getId () .replace ("Z", "+00: 00"); }

4. הכנת אזורים ניתן להשוות

באופן אופציונלי, אנו יכולים גם למיין את אזורי הזמן בהתאם לקיזוז.

לשם כך נשתמש ב- ZoneComparator מעמד:

מחלקה פרטית ZoneComparator מיישמת את Comparator {@Override public int השווה (ZoneId zoneId1, ZoneId zoneId2) {LocalDateTime now = LocalDateTime.now (); ZoneOffset offset1 = now.atZone (zoneId1) .getOffset (); ZoneOffset offset2 = now.atZone (zoneId2) .getOffset (); החזר קיזוז 1. compareTo (קיזוז 2); }}

5. הצגת אזורי זמן

כל שנותר לעשות הוא להרכיב את החלקים הנ"ל על ידי קריאת ה- getTimeZoneList () שיטה לכל אחד OffsetBase enum ערך והצגת הרשימות:

מחלקה ציבורית TimezoneDisplayApp {public static void main (String ... args) {TimezoneDisplay display = new TimezoneDisplay (); System.out.println ("אזורי זמן ב- UTC:"); רשימה utc = display.getTimeZoneList (TimezoneDisplay.OffsetBase.UTC); utc.forEach (System.out :: println); System.out.println ("אזורי זמן ב- GMT:"); רשימה gmt = display.getTimeZoneList (TimezoneDisplay.OffsetBase.GMT); gmt.forEach (System.out :: println); }}

כאשר אנו מריצים את הקוד שלעיל, הוא ידפיס את אזורי הזמן עבור UTC ו- GMT.

הנה קטע מאיך הפלט ייראה:

אזורי זמן ב- UTC: (UTC + 14: 00) Pacific / Apia (UTC + 14: 00) Pacific / Kiritimati (UTC + 14: 00) Pacific / Tongatapu (UTC + 14: 00) וכו '/ GMT-14

6. ג'אווה 7 ולפני

Java 8 מקל על משימה זו באמצעות ה- זרם ו תאריך ושעה ממשקי API.

עם זאת, אם יש לנו Java 7 ולפני פרויקט, אנו עדיין יכולים להשיג את אותה התוצאה על ידי הסתמכות על ה- java.util.TimeZone כיתה עם שלה getAvailableIDs () שיטה:

רשימה ציבורית getTimeZoneList (בסיס OffsetBase) {String [] availableZoneIds = TimeZone.getAvailableIDs (); תוצאת רשימה = ArrayList חדש (availableZoneIds.length); עבור (String zoneId: availableZoneIds) {TimeZone curTimeZone = TimeZone.getTimeZone (zoneId); קיזוז מחרוזת = calcOffset (curTimeZone.getRawOffset ()); result.add (String.format ("(% s% s)% s", בסיס, קיזוז, zoneId)); } Collections.sort (תוצאה); תוצאת החזרה; }

ההבדל העיקרי בקוד Java 8 הוא חישוב הקיזוז.

ה rawOffset אנחנו מגיעים מ אזור זמן()של getRawOffset () השיטה מבטאת את קיזוז אזור הזמן באלפיות השנייה.

לכן, עלינו להמיר זאת לשעות ודקות באמצעות ה- TimeUnit מעמד:

מחרוזת פרטית calcOFset (int rawOffset) {if (rawOffset == 0) {return "+00: 00"; } שעות ארוכות = TimeUnit.MILLISECONDS.toHours (rawOffset); דקות ארוכות = TimeUnit.MILLISECONDS.toMinutes (rawOffset); דקות = Math.abs (דקות - TimeUnit.HOURS.toMinutes (שעות)); החזר String.format ("% + 03d:% 02d", שעות, Math.abs (דקות)); }

7. מסקנה

במדריך מהיר זה, ראינו כיצד אנו יכולים להרכיב רשימה של כל אזורי הזמן הזמינים עם קיזוז UTC ו- GMT שלהם.

וכמו תמיד, קוד המקור המלא של הדוגמאות זמין ב- GitHub.