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);
    }
}

打印时区偏移和显示名称:

这是所有比格林威治标准时间晚 5 小时的时区的快速打印输出。这可以通过调用printAllAvailableTimeZones()方法来实现。这是在调试模式下自动调用的。

-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 教程:时区和偏移类可以帮助您进一步解决问题。

ZoneId 和 ZoneOffset

Date-Time API 提供了两个类用于指定时区或偏移量:

  • ZoneId 指定时区标识符并提供在 Instant 和 LocalDateTime 之间转换的规则。
  • ZoneOffset 指定与格林威治/UTC 时间的时区偏移量。
于 2014-03-22T13:04:38.653 回答