我已经阅读了很多关于这个问题的答案,但无法弄清楚为什么会这样。以下是代码。
在类的构造函数中创建日期格式实例变量:
format = new SimpleDateFormat("ddMMyy",Locale.US);
format.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
然后,用这种方式:
Date d = format.parse("280218");
致电d.toString()
给出:
在后续代码中解析IST日期字符串会得到ParseException
,而带有GMT的字符串会被成功解析。
知道为什么会这样吗?
答案 0 :(得分:0)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyy", Locale.US);
LocalDate d = LocalDate.parse("280218", formatter);
String dToString = d.toString();
System.out.println(dToString);
LocalDate parsedBack = LocalDate.parse(dToString);
System.out.println(parsedBack);
打印(两条相同的行):
2018-02-28
2018-02-28
所有设备的结果都是一样的。
我不确定你为什么要做你正在做的事情,所以我可能没有完全击中你所追求的。我试图仅使用java.time
而不是过时的Date
和SimpleDateFormat
类来尽可能地模仿您的代码。它走得更顺利。 java.time
是现代Java日期和时间API,通常可以更好地使用它。
由于LocalDate
是没有时间或时区的日期,因此从一开始就消除了时区差异的问题。 LocalDate.toString()
始终在所有设备上提供相同的字符串。另外,LocalDate
在没有显式格式化程序的情况下解析相同的字符串。这简直太容易了。
如果您的Android级别不够高,无法在本机使用java.time
,请将ThreeTenABP添加到您的项目中,并确保导入org.threeten.bp.LocalDate
和org.threeten.bp.format.DateTimeFormatter
。
Date.toString()
用于生成字符串的时区与用于解析日期的格式化程序无关。虽然没有正式记录,但该方法使用JVM的时区设置。我无法保证它可以在您的设备上运行,但至少在我的Mac上我可以通过
Date.toString()
的结果
System.setProperty("user.timezone", "Asia/Kolkata");
或
System.setProperty("user.timezone", "GMT+05:30");
通过这种方式,我可以获得您从不同设备获得的结果。但是,三个和四个字母的时区缩写是不明确的,通常不是真正的时区,所以不要依赖它们来解析Date.toString()
的字符串。 BTW TimeZone.setDefault()
具有相同的效果,可能被认为更高级别;只是我养成了避免过时的日期时间课程的习惯,包括TimeZone
。
java.time
。java.time
向Java 6和7的后端(JST-310的ThreeTen)