1

ここで解決しなければならない問題がありますが、方法がわかりません。

私はこれをしなければなりません:

ShowCurrentTime.java、現在の時刻を GMT で表示するプログラムを提供します。プログラムを修正して、タイム ゾーン オフセットを GMT に入力するようユーザーに促し、指定されたタイム ゾーンの時刻を表示するようにします。

実行例は次のとおりです。

これまでのところ、デフォルトの GMT 時刻を実行しましたが、その方法がまったくわかりません..

package ex;

import java.util.*;
import java.text.*;

public class GMT {
   public static void main(String[] args) {       
        final Date currentTime = new Date();
        final SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");

        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

        System.out.println("GMT time: " + sdf.format(currentTime));  
    }
}
4

1 に答える 1

1

序章

この新しく改善されたコードに対する元の回答を破棄しました。全てを一から書き直しました。

プログラムは、タイム ゾーン ID に基づいてタイム ゾーンを設定できるだけでなく、GMT オフセットの時間と分を解析することもできます。部分的な時間 (分ありまたはなし) を入力することもできます! このコードは、正規表現を使用して GMT オフセット時間を解釈するため、非常に動的です。できるだけ包括的になるように努めました。

以下の出力は、以下に記述されたコードによって生成されました。

Current time: Sat, Mar 22, 2014 07:12:22 PM EDT (GMT+00:00)
Enter a timezone: Africa/Cairo
Sun, Mar 23, 2014 01:12:22 AM EET (Eastern European Time)
Continue? (y/n): y
Enter a timezone: America/Los_Angeles
Sat, Mar 22, 2014 04:12:22 PM PDT (Pacific Standard Time)
Continue? (y/n): y
Enter a timezone: GMT-05:00
Sat, Mar 22, 2014 06:12:22 PM GMT-05:00 (GMT-05:00)
Continue? (y/n): y
Enter a timezone: GMT-4:30
Sat, Mar 22, 2014 06:42:22 PM GMT-04:30 (GMT-04:30)
Continue? (y/n): y
Enter a timezone: 8
Sun, Mar 23, 2014 07:12:22 AM GMT+08:00 (GMT+08:00)
Continue? (y/n): y
Enter a timezone: 11:30
Sun, Mar 23, 2014 10:42:22 AM GMT+11:30 (GMT+11:30)
Continue? (y/n): y
Enter a timezone: FooBar
[ERROR] Could not parse GMT ID!
[ERROR] Invalid GMT TimeZone ID!
Sun, Mar 23, 2014 10:42:22 AM GMT+11:30 (GMT+11:30)
Continue? (y/n): y
Enter a timezone: Asia/Tokyo
Sun, Mar 23, 2014 08:12:22 AM JST (Japan Standard Time)
Continue? (y/n): n
Done...

完全な例:

以下のコードは、あなたが要求したことを実行する必要があります。

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TimeZoneFormatter {
    private static final DateFormat DEFAULT_DATE_FORMAT = new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");
    private static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone("GMT+00:00");
    private static final Pattern GMT_PATTERN = Pattern.compile("(?:GMT)?([+-])?([012]?\\d)(:([0-5]?\\d))?");
    private static final Pattern REMOVE_LEADING_ZEROS = Pattern.compile("^0+(?!$)");
    private static final Set<String> VALID_IDS = new LinkedHashSet<String>(Arrays.asList(TimeZone.getAvailableIDs()));
    private static final boolean DEBUG = true;

    private DateFormat dateFormat;
    private TimeZone timeZone;

    public TimeZoneFormatter() {
        this(DEFAULT_DATE_FORMAT);
    }

    public TimeZoneFormatter(DateFormat dateFormat) {
        this.dateFormat = dateFormat;
        this.timeZone = GMT_TIME_ZONE;
    }

    public void setDateFormat(DateFormat dateFormat) {
        this.dateFormat = dateFormat;
    }

    public void setTimezone(boolean positive, int hours, int minutes) {
        String timeZoneId = formatGmtId(positive, hours, minutes);
        setTimezone(timeZoneId);
    }

    public void setTimezone(String timeZoneId) {
        TimeZone newTimeZone = TimeZone.getTimeZone(timeZoneId);

        if (timeZone.getRawOffset() != 0 && newTimeZone.getRawOffset() == 0) {
            System.out.println("[ERROR] Invalid GMT TimeZone ID!");
        } else {
            timeZone = newTimeZone;
            dateFormat.setTimeZone(timeZone);
        }
    }

    public DateFormat getDateFormat() {
        return dateFormat;
    }

    public String getTimezoneId() {
        return timeZone.getID();
    }

    // -------------------------------------------------------------------------
    // Begin internal parsing and formatting methods.
    // -------------------------------------------------------------------------

    private String parseGmtTimeZoneId(String id) {
        Matcher m = GMT_PATTERN.matcher(id);

        if (m.find()) {
            char sign = m.group(1) != null ? m.group(1).charAt(0) : '+';
            int hours = removeLeadingZeros(m.group(2));
            int minutes = 0;

            if (m.group(3) != null) {
                minutes = removeLeadingZeros(m.group(4));
            }

            return formatGmtId(sign, hours, minutes);
        }

        if (!VALID_IDS.contains(id)) {
            System.out.println("[ERROR] Could not parse GMT ID!");
        }

        return id;
    }

    private void setGmtTimezone(String gmtOffset) {
        String timeZoneId = parseGmtTimeZoneId(gmtOffset);
        setTimezone(timeZoneId);
    }

    private String formatGmtId(boolean positive, int hours, int minutes) {
        return formatGmtId(positive ? '+' : '-', hours, minutes);
    }

    private String formatGmtId(char sign, int hours, int minutes) {
        return String.format("GMT%c%02d:%02d", sign, hours, minutes);
    }

    private int removeLeadingZeros(String intStr) {
        return Integer.parseInt(intStr.replaceAll(REMOVE_LEADING_ZEROS.pattern(), ""));
    }

    private String formatDate(final Date time) {
        return String.format("%s (%s)", dateFormat.format(time),
                timeZone.getDisplayName());
    }

    // -------------------------------------------------------------------------
    // Begin main method and other static utility methods.
    // -------------------------------------------------------------------------

    public static void main(String[] args) {
        if (DEBUG) {
            printAllAvailableTimeZones();
        }

        final Date time = new Date();
        TimeZoneFormatter frmt = new TimeZoneFormatter();
        Scanner scan = new Scanner(System.in);

        try {
            System.out.printf("Current time: ");
            printDate(time, frmt);

            while (true) {
                System.out.print("Enter a timezone: ");
                frmt.setGmtTimezone(scan.nextLine());
                printDate(time, frmt);

                System.out.print("Continue? (y/n): ");
                String response = scan.nextLine().trim();
                if ((response.length() < 1 ? 'y' : response.charAt(0)) == 'n') {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            scan.close();
        }

        System.out.println("Done...");
    }

    public static void printDate(final Date date, TimeZoneFormatter formatter) {
        if (date == null) {
            throw new IllegalArgumentException("Please enter a non-null date.");
        }

        if (formatter == null) {
            formatter = new TimeZoneFormatter();
        }

        System.out.println(formatter.formatDate(date));
    }   

    public static void printAllAvailableTimeZones() {
        System.out.println("Available Time Zones:");
        List<TimeZone> timeZones = new ArrayList<TimeZone>();

        for (String id : VALID_IDS) {
            timeZones.add(TimeZone.getTimeZone(id));
        }

        Collections.sort(timeZones, new Comparator<TimeZone>() {
            @Override
            public int compare(TimeZone t1, TimeZone t2) {
                int offsetDiff = t1.getRawOffset() - t2.getRawOffset();

                if (offsetDiff == 0) {
                    int nameDiff = t1.getDisplayName().compareTo(t2.getDisplayName());

                    if (nameDiff == 0) {
                        return t1.getID().compareTo(t2.getID());
                    } else {
                        return nameDiff;
                    }
                } else {
                    return offsetDiff;
                }
            }
        });

        for (TimeZone timeZone : timeZones) {
            System.out.printf("%s : %32s : %s%n", getFormattedOffset(timeZone),
                    timeZone.getID(), timeZone.getDisplayName());
        }

        System.out.println();
    }

    private static String getFormattedOffset(TimeZone timeZone) {
        int offset = timeZone.getRawOffset();
        char sign = offset < 0 ? '-' : '+';

        if (offset < 0) {
            offset *= -1;
        }

        int hours = offset / 3600000;
        int mins = (offset % 3600000) / 60000;

        return String.format("%c%02d:%02d", sign, hours, mins);
    }
}

TimeZone オフセットと表示名の出力:

これは、GMT 時間から 5 時間遅れているすべてのタイム ゾーンの簡単な印刷です。これは、メソッドを呼び出すことで実現できますprintAllAvailableTimeZones()これは、 DEBUGモードで自動的に呼び出されます。

-05:00 :                   America/Bogota : Colombia Time
-05:00 :                   America/Havana : Cuba Standard Time
-05:00 :                             Cuba : Cuba Standard Time
-05:00 :                 America/Atikokan : Eastern Standard Time
-05:00 :                   America/Cayman : Eastern Standard Time
-05:00 :            America/Coral_Harbour : Eastern Standard Time
-05:00 :                  America/Detroit : Eastern Standard Time
-05:00 :               America/Fort_Wayne : Eastern Standard Time
-05:00 :               America/Grand_Turk : Eastern Standard Time
-05:00 :     America/Indiana/Indianapolis : Eastern Standard Time
-05:00 :          America/Indiana/Marengo : Eastern Standard Time
-05:00 :       America/Indiana/Petersburg : Eastern Standard Time
-05:00 :            America/Indiana/Vevay : Eastern Standard Time
-05:00 :        America/Indiana/Vincennes : Eastern Standard Time
-05:00 :          America/Indiana/Winamac : Eastern Standard Time
-05:00 :             America/Indianapolis : Eastern Standard Time
-05:00 :                  America/Iqaluit : Eastern Standard Time
-05:00 :                  America/Jamaica : Eastern Standard Time
-05:00 :      America/Kentucky/Louisville : Eastern Standard Time
-05:00 :      America/Kentucky/Monticello : Eastern Standard Time
-05:00 :               America/Louisville : Eastern Standard Time
-05:00 :                 America/Montreal : Eastern Standard Time
-05:00 :                   America/Nassau : Eastern Standard Time
-05:00 :                 America/New_York : Eastern Standard Time
-05:00 :                  America/Nipigon : Eastern Standard Time
-05:00 :                   America/Panama : Eastern Standard Time
-05:00 :              America/Pangnirtung : Eastern Standard Time
-05:00 :           America/Port-au-Prince : Eastern Standard Time
-05:00 :              America/Thunder_Bay : Eastern Standard Time
-05:00 :                  America/Toronto : Eastern Standard Time
-05:00 :                   Canada/Eastern : Eastern Standard Time
-05:00 :                              EST : Eastern Standard Time
-05:00 :                          EST5EDT : Eastern Standard Time
-05:00 :                              IET : Eastern Standard Time
-05:00 :                          Jamaica : Eastern Standard Time
-05:00 :                     SystemV/EST5 : Eastern Standard Time
-05:00 :                  SystemV/EST5EDT : Eastern Standard Time
-05:00 :                  US/East-Indiana : Eastern Standard Time
-05:00 :                       US/Eastern : Eastern Standard Time
-05:00 :                      US/Michigan : Eastern Standard Time
-05:00 :                America/Guayaquil : Ecuador Time
-05:00 :                        Etc/GMT+5 : GMT-05:00
-05:00 :                     America/Lima : Peru Time

その他のリソース:

次の Oracle チュートリアル: Time Zone and Offset Classesが問題の解決に役立つ場合があります。

ZoneId と ZoneOffset

Date-Time API には、タイム ゾーンまたはオフセットを指定するための 2 つのクラスが用意されています。

  • ZoneId は、タイム ゾーン識別子を指定し、Instant と LocalDateTime の間で変換するための規則を提供します。
  • ZoneOffset は、グリニッジ/UTC 時間からのタイム ゾーン オフセットを指定します。
于 2014-03-22T13:04:38.653 に答える