【发布时间】:2021-03-28 03:59:59
【问题描述】:
此代码示例使用 3 个时区(EST、PST、EET)。 对于每个时区,创建一个 Date 对象并运行 toString() 以打印出正在使用的格式。 然后这个相同的字符串值被传递给构造函数并用于创建一个新的日期对象。 代码会运行检查以确保所使用的时区有效。
所有 3 个时区(EST、PST、EET)均有效,但在创建对象时,仅为 EET 返回 java.lang.IllegalArgumentException。
import java.util.*;
import java.text.*;
public class DateTest
{
public static void main (String[] args)
{
System.out.println("=======Test 1 : using EST=======");
isValidTimeZone("EST");
TimeZone.setDefault(TimeZone.getTimeZone("EST"));
runTest();
System.out.println("=======Test 2 : using PST=======");
isValidTimeZone("PST");
TimeZone.setDefault(TimeZone.getTimeZone("PST"));
runTest();
System.out.println("=======Test 3 : using EET=======");
isValidTimeZone("EET");
TimeZone.setDefault(TimeZone.getTimeZone("EET"));
runTest();
}
private static void isValidTimeZone(String tz)
{
String[] validIDs = TimeZone.getAvailableIDs();
boolean validTZ = false;
for (String str : validIDs) {
if (str != null && str.equals(tz)) {
validTZ = true;
break;
}
}
if (validTZ)
{
System.out.println(tz + " is a Valid Time Zone");
}
else
{
System.out.println(tz + " is **NOT** a Valid Time Zone");
}
}
private static void runTest()
{
try
{
String myDateString = new Date().toString();
System.out.println(" Default Date String : " + myDateString);
MyObjectWithADate myObject = new MyObjectWithADate(new Date(myDateString));
}
catch(Exception e)
{
System.out.println(" Object NOT Created!!!!!");
e.printStackTrace(System.out);
}
}
}
public MyObjectWithADate (Date eventDate)
{
System.out.println(" Passed in Date : " + eventDate.toString());
// this.eventDate = eventDate;
try {
this.eventDate = DateFormat.getInstance().parse(eventDate.toString());
System.out.println(" Object Created");
} catch (ParseException e) {
System.out.println(" Object NOT Created");
e.printStackTrace();
}
}
}
这是输出。
基于 Java 11 文档,它确实注释了 Date 已被弃用并且应该使用 DateFormat.parse()。
作为测试,对象的代码被修改为使用 DateFormat.parse 但这只会让事情变得更糟。
public MyObjectWithADate (Date eventDate)
{
System.out.println(" Passed in Date : " + eventDate.toString());
// this.eventDate = eventDate;
try {
this.eventDate = DateFormat.getInstance().parse(eventDate.toString());
System.out.println(" Object Created");
} catch (ParseException e) {
System.out.println(" Object NOT Created");
e.printStackTrace();
}
}
}
这是新结果。
问题 1: JVM从哪个环境变量获取时区?
问题 2: 使用原始代码,为什么使用与JVM提供的格式相同的格式时会出现异常?
问题 3: EET 的具体原因是什么导致它在 EST 和 PST 中失败并在没有问题的情况下进行交换?
问题 4: 如果我想允许任何时区的任何人运行原始代码,需要更改什么?
编辑添加以下内容:
上面的代码是一个缩小的模型。不幸的是,不能在所有地方修改实际代码以更改使用 Date 对象。
我确实使用 MyObjectWithADate 对象中的 SimpleDateFormat 运行了另一个测试。这再次适用于 EST 和 PST,但不适用于 EET。
class MyObjectWithADate
{
private Date eventDate;
public MyObjectWithADate (Date eventDate)
{
System.out.println(" Passed in Date : " + eventDate.toString());
String datePattern = new String ("E MMM dd HH:mm:ss z yyyy");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
try {
this.eventDate = simpleDateFormat.parse(eventDate.toString());
System.out.println(" Object Created");
} catch (ParseException e) {
System.out.println(" Object NOT Created");
e.printStackTrace();
}
System.out.println(" Object Created");
}
}
我开始认为我最初的问题应该是,如何获取以下字符串
2021 年 3 月 26 日星期五 21:42:52 EET
并将其放入 Date 对象中。
【问题讨论】:
-
完全不相关,不解决上述任何问题。对在代码中设置时区不感兴趣,也不对作为设置传入。
-
您是说“3.1.设置环境变量”部分没有告诉您哪个环境变量设置时区?请不要这么立即不屑一顾。
-
我建议你不要使用
TimeZone、Date和DateFormat。这些类设计不良且过时,尤其是最后一个以麻烦着称。而是使用java.time, the modern Java date and time API。 -
Real time zones 具有
Continent/Region格式的名称,例如America/Los_Angeles、Africa/Tunis和Pacific/Auckland。 EST、PST、EET 不是时区。
标签: java date exception timezone java.util.date