我有一个问题需要解决,但我不知道如何解决?
我必须这样做:
,给出一个显示当前时间的程序 在格林威治标准时间。修改程序,使其提示用户输入 与 GMT 的时区偏移并显示指定时间的时间 区。ShowCurrentTime.java
这是一个示例运行:
到目前为止我已经完成了默认的 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));
}
}
我已经放弃了对这个新的和改进的代码的原始答案。我从头开始重写了一切。
程序不仅可以根据时区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);
}
}
这里是所有比 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 教程:时区和偏移类可以进一步帮助您解决问题。
ZoneId 和 ZoneOffset
Date-Time API 提供了两个类来指定时区或偏移量:
- ZoneId 指定时区标识符并提供 Instant 和 LocalDateTime 之间的转换规则。
- ZoneOffset 指定与格林威治/UTC 时间的时区偏移。
java.time
2014 年 3 月,Java 8 引入了现代的
java.time
日期时间 API,取代了容易出错的旧版java.util
日期时间 API。任何新代码都应使用 java.time
API。
java.time
API 的解决方案Instant#now
获取当前时刻。OffsetDateTime
,以表示用户使用 Instant#atOffset
输入的偏移量。演示:
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Instant now = Instant.now();
System.out.println("The current moment: " + now);
System.out.print("Enter a time zone offset (e.g. -04:00): ");
ZoneOffset offset = ZoneOffset.UTC;
try {
offset = ZoneOffset.of(scanner.nextLine());
} catch (DateTimeParseException e) {
System.out.println("Error parsing the offset: " + e);
}
OffsetDateTime odt = now.atOffset(offset);
System.out.printf("The date-time at %s is: %s%n", offset, odt);
}
}
示例运行:
The current moment: 2025-01-22T14:15:53.819823900Z
Enter a time zone offset (e.g. -04:00): +05:30
The date-time at +05:30 is: 2025-01-22T19:45:53.819823900+05:30
另一个示例运行:
The current moment: 2025-01-22T14:25:45.464184200Z
Enter a time zone offset (e.g. -04:00): -05:00
The date-time at -05:00 is: 2025-01-22T09:25:45.464184200-05:00
从 Trail:日期时间了解有关现代日期时间 API 的更多信息。